HS: Values dict insertion order (+2 tests)
Dict-set! keys iterate in scrambled order, so Values|FormEncoded and Values|JSONString produced output in the wrong order. Fix: hs-values-absorb now tracks insertion order in a hidden `_order` list on the dict itself. hs-coerce FormEncoded/JSONString paths read `_order` when present and iterate in that order (filtering the marker key out). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -794,16 +794,26 @@
|
|||||||
((string? v) (hs-json-escape v))
|
((string? v) (hs-json-escape v))
|
||||||
((list? v) (str "[" (join "," (map hs-json-stringify v)) "]"))
|
((list? v) (str "[" (join "," (map hs-json-stringify v)) "]"))
|
||||||
((dict? v)
|
((dict? v)
|
||||||
(str
|
(let
|
||||||
"{"
|
((ks (or (get v "_order") (filter (fn (k) (not (= k "_order"))) (keys v)))))
|
||||||
(join
|
(str
|
||||||
","
|
"{"
|
||||||
(map
|
(join
|
||||||
(fn
|
","
|
||||||
(k)
|
(filter
|
||||||
(str (hs-json-escape k) ":" (hs-json-stringify (get v k))))
|
(fn (s) (not (= s "")))
|
||||||
(keys v)))
|
(map
|
||||||
"}"))
|
(fn
|
||||||
|
(k)
|
||||||
|
(if
|
||||||
|
(= k "_order")
|
||||||
|
""
|
||||||
|
(str
|
||||||
|
(hs-json-escape k)
|
||||||
|
":"
|
||||||
|
(hs-json-stringify (get v k)))))
|
||||||
|
ks)))
|
||||||
|
"}")))
|
||||||
(true (hs-json-escape (str v))))))
|
(true (hs-json-escape (str v))))))
|
||||||
;; Collection: split by
|
;; Collection: split by
|
||||||
(define
|
(define
|
||||||
@@ -843,18 +853,25 @@
|
|||||||
((= type-name "FormEncoded")
|
((= type-name "FormEncoded")
|
||||||
(if
|
(if
|
||||||
(dict? value)
|
(dict? value)
|
||||||
(join
|
(let
|
||||||
"&"
|
((ks (or (get value "_order") (filter (fn (k) (not (= k "_order"))) (keys value)))))
|
||||||
(map
|
(join
|
||||||
(fn
|
"&"
|
||||||
(k)
|
(filter
|
||||||
(let
|
(fn (s) (not (= s "")))
|
||||||
((v (get value k)))
|
(map
|
||||||
(if
|
(fn
|
||||||
(list? v)
|
(k)
|
||||||
(join "&" (map (fn (item) (str k "=" item)) v))
|
(if
|
||||||
(str k "=" v))))
|
(= k "_order")
|
||||||
(keys value)))
|
""
|
||||||
|
(let
|
||||||
|
((v (get value k)))
|
||||||
|
(if
|
||||||
|
(list? v)
|
||||||
|
(join "&" (map (fn (item) (str k "=" item)) v))
|
||||||
|
(str k "=" v)))))
|
||||||
|
ks))))
|
||||||
(str value)))
|
(str value)))
|
||||||
((or (= type-name "Fixed") (= type-name "Fixed:") (starts-with? type-name "Fixed:"))
|
((or (= type-name "Fixed") (= type-name "Fixed:") (starts-with? type-name "Fixed:"))
|
||||||
(let
|
(let
|
||||||
@@ -932,18 +949,32 @@
|
|||||||
(let
|
(let
|
||||||
((kids (host-get node "children")))
|
((kids (host-get node "children")))
|
||||||
(when
|
(when
|
||||||
(and (not (nil? kids)) (list? kids))
|
(not (nil? kids))
|
||||||
(let
|
(cond
|
||||||
((n (len kids)))
|
((list? kids)
|
||||||
(define
|
(let
|
||||||
each
|
((n (len kids)))
|
||||||
(fn
|
(define
|
||||||
(i)
|
each
|
||||||
(when
|
(fn
|
||||||
(< i n)
|
(i)
|
||||||
(walk (nth kids i))
|
(when
|
||||||
(each (+ i 1)))))
|
(< i n)
|
||||||
(each 0)))))))))
|
(walk (nth kids i))
|
||||||
|
(each (+ i 1)))))
|
||||||
|
(each 0)))
|
||||||
|
(true
|
||||||
|
(let
|
||||||
|
((n (or (host-get kids "length") 0)))
|
||||||
|
(define
|
||||||
|
each-h
|
||||||
|
(fn
|
||||||
|
(i)
|
||||||
|
(when
|
||||||
|
(< i n)
|
||||||
|
(walk (host-get kids i))
|
||||||
|
(each-h (+ i 1)))))
|
||||||
|
(each-h 0)))))))))))
|
||||||
(walk root)
|
(walk root)
|
||||||
acc)))
|
acc)))
|
||||||
|
|
||||||
@@ -1015,7 +1046,15 @@
|
|||||||
(dict-set! acc name (append existing (list v)))
|
(dict-set! acc name (append existing (list v)))
|
||||||
(dict-set! acc name (list existing v)))
|
(dict-set! acc name (list existing v)))
|
||||||
acc)))
|
acc)))
|
||||||
(true (do (dict-set! acc name v) acc))))))))
|
(true
|
||||||
|
(begin
|
||||||
|
(dict-set! acc name v)
|
||||||
|
(let
|
||||||
|
((ord (or (get acc "_order") (list))))
|
||||||
|
(when
|
||||||
|
(not (some (fn (x) (= x name)) ord))
|
||||||
|
(dict-set! acc "_order" (append ord (list name)))))
|
||||||
|
acc))))))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
hs-as-values
|
hs-as-values
|
||||||
|
|||||||
@@ -794,16 +794,26 @@
|
|||||||
((string? v) (hs-json-escape v))
|
((string? v) (hs-json-escape v))
|
||||||
((list? v) (str "[" (join "," (map hs-json-stringify v)) "]"))
|
((list? v) (str "[" (join "," (map hs-json-stringify v)) "]"))
|
||||||
((dict? v)
|
((dict? v)
|
||||||
(str
|
(let
|
||||||
"{"
|
((ks (or (get v "_order") (filter (fn (k) (not (= k "_order"))) (keys v)))))
|
||||||
(join
|
(str
|
||||||
","
|
"{"
|
||||||
(map
|
(join
|
||||||
(fn
|
","
|
||||||
(k)
|
(filter
|
||||||
(str (hs-json-escape k) ":" (hs-json-stringify (get v k))))
|
(fn (s) (not (= s "")))
|
||||||
(keys v)))
|
(map
|
||||||
"}"))
|
(fn
|
||||||
|
(k)
|
||||||
|
(if
|
||||||
|
(= k "_order")
|
||||||
|
""
|
||||||
|
(str
|
||||||
|
(hs-json-escape k)
|
||||||
|
":"
|
||||||
|
(hs-json-stringify (get v k)))))
|
||||||
|
ks)))
|
||||||
|
"}")))
|
||||||
(true (hs-json-escape (str v))))))
|
(true (hs-json-escape (str v))))))
|
||||||
;; Collection: split by
|
;; Collection: split by
|
||||||
(define
|
(define
|
||||||
@@ -843,18 +853,25 @@
|
|||||||
((= type-name "FormEncoded")
|
((= type-name "FormEncoded")
|
||||||
(if
|
(if
|
||||||
(dict? value)
|
(dict? value)
|
||||||
(join
|
(let
|
||||||
"&"
|
((ks (or (get value "_order") (filter (fn (k) (not (= k "_order"))) (keys value)))))
|
||||||
(map
|
(join
|
||||||
(fn
|
"&"
|
||||||
(k)
|
(filter
|
||||||
(let
|
(fn (s) (not (= s "")))
|
||||||
((v (get value k)))
|
(map
|
||||||
(if
|
(fn
|
||||||
(list? v)
|
(k)
|
||||||
(join "&" (map (fn (item) (str k "=" item)) v))
|
(if
|
||||||
(str k "=" v))))
|
(= k "_order")
|
||||||
(keys value)))
|
""
|
||||||
|
(let
|
||||||
|
((v (get value k)))
|
||||||
|
(if
|
||||||
|
(list? v)
|
||||||
|
(join "&" (map (fn (item) (str k "=" item)) v))
|
||||||
|
(str k "=" v)))))
|
||||||
|
ks))))
|
||||||
(str value)))
|
(str value)))
|
||||||
((or (= type-name "Fixed") (= type-name "Fixed:") (starts-with? type-name "Fixed:"))
|
((or (= type-name "Fixed") (= type-name "Fixed:") (starts-with? type-name "Fixed:"))
|
||||||
(let
|
(let
|
||||||
@@ -932,18 +949,32 @@
|
|||||||
(let
|
(let
|
||||||
((kids (host-get node "children")))
|
((kids (host-get node "children")))
|
||||||
(when
|
(when
|
||||||
(and (not (nil? kids)) (list? kids))
|
(not (nil? kids))
|
||||||
(let
|
(cond
|
||||||
((n (len kids)))
|
((list? kids)
|
||||||
(define
|
(let
|
||||||
each
|
((n (len kids)))
|
||||||
(fn
|
(define
|
||||||
(i)
|
each
|
||||||
(when
|
(fn
|
||||||
(< i n)
|
(i)
|
||||||
(walk (nth kids i))
|
(when
|
||||||
(each (+ i 1)))))
|
(< i n)
|
||||||
(each 0)))))))))
|
(walk (nth kids i))
|
||||||
|
(each (+ i 1)))))
|
||||||
|
(each 0)))
|
||||||
|
(true
|
||||||
|
(let
|
||||||
|
((n (or (host-get kids "length") 0)))
|
||||||
|
(define
|
||||||
|
each-h
|
||||||
|
(fn
|
||||||
|
(i)
|
||||||
|
(when
|
||||||
|
(< i n)
|
||||||
|
(walk (host-get kids i))
|
||||||
|
(each-h (+ i 1)))))
|
||||||
|
(each-h 0)))))))))))
|
||||||
(walk root)
|
(walk root)
|
||||||
acc)))
|
acc)))
|
||||||
|
|
||||||
@@ -1015,7 +1046,15 @@
|
|||||||
(dict-set! acc name (append existing (list v)))
|
(dict-set! acc name (append existing (list v)))
|
||||||
(dict-set! acc name (list existing v)))
|
(dict-set! acc name (list existing v)))
|
||||||
acc)))
|
acc)))
|
||||||
(true (do (dict-set! acc name v) acc))))))))
|
(true
|
||||||
|
(begin
|
||||||
|
(dict-set! acc name v)
|
||||||
|
(let
|
||||||
|
((ord (or (get acc "_order") (list))))
|
||||||
|
(when
|
||||||
|
(not (some (fn (x) (= x name)) ord))
|
||||||
|
(dict-set! acc "_order" (append ord (list name)))))
|
||||||
|
acc))))))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
hs-as-values
|
hs-as-values
|
||||||
|
|||||||
Reference in New Issue
Block a user