diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 616c1e53..3f953c43 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -2142,6 +2142,19 @@ :buffer (string x) x)) +(defn thaw + `Thaw an object (make it mutable) and do a deep copy, making + child value also mutable. Closures, fibers, and abstract + types will not be recursively thawed, but all other types will` + [ds] + (case (type ds) + :array (walk-ind thaw ds) + :tuple (walk-ind thaw ds) + :table (walk-dict thaw (table/proto-flatten ds)) + :struct (walk-dict thaw (struct/proto-flatten ds)) + :string (buffer ds) + ds)) + (defn macex ``Expand macros completely. `on-binding` is an optional callback for whenever a normal symbolic binding diff --git a/test/suite0010.janet b/test/suite0010.janet index 5ac0cd16..b41142e8 100644 --- a/test/suite0010.janet +++ b/test/suite0010.janet @@ -253,4 +253,13 @@ # Check missing struct proto bug. (assert (struct/getproto (struct/with-proto {:a 1} :b 2 :c nil)) "missing struct proto") +# Test thaw and freeze +(def table-to-freeze @{:c 22 :b [1 2 3 4] :d @"test" :e "test2"}) +(def table-to-freeze-with-inline-proto @{:a @[1 2 3] :b @[1 2 3 4] :c 22 :d @"test" :e @"test2"}) +(def struct-to-thaw (struct/with-proto {:a [1 2 3]} :c 22 :b [1 2 3 4] :d "test" :e "test2")) +(table/setproto table-to-freeze @{:a @[1 2 3]}) +(assert (deep= {:a [1 2 3] :b [1 2 3 4] :c 22 :d "test" :e "test2"} (freeze table-to-freeze))) +(assert (deep= table-to-freeze-with-inline-proto (thaw table-to-freeze))) +(assert (deep= table-to-freeze-with-inline-proto (thaw struct-to-thaw))) + (end-suite)