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))
|
||||
((list? v) (str "[" (join "," (map hs-json-stringify v)) "]"))
|
||||
((dict? v)
|
||||
(str
|
||||
"{"
|
||||
(join
|
||||
","
|
||||
(map
|
||||
(fn
|
||||
(k)
|
||||
(str (hs-json-escape k) ":" (hs-json-stringify (get v k))))
|
||||
(keys v)))
|
||||
"}"))
|
||||
(let
|
||||
((ks (or (get v "_order") (filter (fn (k) (not (= k "_order"))) (keys v)))))
|
||||
(str
|
||||
"{"
|
||||
(join
|
||||
","
|
||||
(filter
|
||||
(fn (s) (not (= s "")))
|
||||
(map
|
||||
(fn
|
||||
(k)
|
||||
(if
|
||||
(= k "_order")
|
||||
""
|
||||
(str
|
||||
(hs-json-escape k)
|
||||
":"
|
||||
(hs-json-stringify (get v k)))))
|
||||
ks)))
|
||||
"}")))
|
||||
(true (hs-json-escape (str v))))))
|
||||
;; Collection: split by
|
||||
(define
|
||||
@@ -843,18 +853,25 @@
|
||||
((= type-name "FormEncoded")
|
||||
(if
|
||||
(dict? value)
|
||||
(join
|
||||
"&"
|
||||
(map
|
||||
(fn
|
||||
(k)
|
||||
(let
|
||||
((v (get value k)))
|
||||
(if
|
||||
(list? v)
|
||||
(join "&" (map (fn (item) (str k "=" item)) v))
|
||||
(str k "=" v))))
|
||||
(keys value)))
|
||||
(let
|
||||
((ks (or (get value "_order") (filter (fn (k) (not (= k "_order"))) (keys value)))))
|
||||
(join
|
||||
"&"
|
||||
(filter
|
||||
(fn (s) (not (= s "")))
|
||||
(map
|
||||
(fn
|
||||
(k)
|
||||
(if
|
||||
(= k "_order")
|
||||
""
|
||||
(let
|
||||
((v (get value k)))
|
||||
(if
|
||||
(list? v)
|
||||
(join "&" (map (fn (item) (str k "=" item)) v))
|
||||
(str k "=" v)))))
|
||||
ks))))
|
||||
(str value)))
|
||||
((or (= type-name "Fixed") (= type-name "Fixed:") (starts-with? type-name "Fixed:"))
|
||||
(let
|
||||
@@ -932,18 +949,32 @@
|
||||
(let
|
||||
((kids (host-get node "children")))
|
||||
(when
|
||||
(and (not (nil? kids)) (list? kids))
|
||||
(let
|
||||
((n (len kids)))
|
||||
(define
|
||||
each
|
||||
(fn
|
||||
(i)
|
||||
(when
|
||||
(< i n)
|
||||
(walk (nth kids i))
|
||||
(each (+ i 1)))))
|
||||
(each 0)))))))))
|
||||
(not (nil? kids))
|
||||
(cond
|
||||
((list? kids)
|
||||
(let
|
||||
((n (len kids)))
|
||||
(define
|
||||
each
|
||||
(fn
|
||||
(i)
|
||||
(when
|
||||
(< i n)
|
||||
(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)
|
||||
acc)))
|
||||
|
||||
@@ -1015,7 +1046,15 @@
|
||||
(dict-set! acc name (append existing (list v)))
|
||||
(dict-set! acc name (list existing v)))
|
||||
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
|
||||
hs-as-values
|
||||
|
||||
Reference in New Issue
Block a user