From 1749e71f327d94805fdbb50d0cbbd692f696997d Mon Sep 17 00:00:00 2001 From: Dominic Monroe Date: Sun, 16 Feb 2020 12:13:41 +0000 Subject: [PATCH] Fix metadata preservation Close #86 --- src/aero/alpha/core.cljc | 12 ++++++++---- src/aero/core.cljc | 2 +- src/aero/impl/walk.cljc | 22 ++++++++++++++++++++++ test/aero/core_test.cljc | 20 +++++++++++++++++++- 4 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/aero/impl/walk.cljc diff --git a/src/aero/alpha/core.cljc b/src/aero/alpha/core.cljc index 1067c3b..b0022d3 100644 --- a/src/aero/alpha/core.cljc +++ b/src/aero/alpha/core.cljc @@ -22,22 +22,26 @@ (and (map? x) (not (record? x))) (with-meta (into [] x) - {`reassemble (fn [_ queue] (into {} queue))}) + {`reassemble (fn [_ queue] (into (empty x) queue))}) (set? x) (with-meta (map-indexed (fn [idx v] [idx v]) x) {`reassemble (fn [_ queue] - (set (map second queue)))}) + (into (empty x) + (map second queue)))}) (vector? x) (with-meta (map-indexed (fn [idx v] [idx v]) x) {`reassemble (fn [_ queue] - (mapv second (sort-by first queue)))}) + (into (empty x) + (mapv second (sort-by first queue))))}) (seq? x) (with-meta (map-indexed (fn [idx v] [idx v]) x) {`reassemble (fn [_ queue] - (apply list (map second (sort-by first queue))))}) + (with-meta + (apply list (map second (sort-by first queue))) + (meta x)))}) ;; Scalar value :else nil)) diff --git a/src/aero/core.cljc b/src/aero/core.cljc index 696c31d..b70b436 100644 --- a/src/aero/core.cljc +++ b/src/aero/core.cljc @@ -5,7 +5,7 @@ [aero.alpha.core :refer [expand expand-scalar-repeatedly expand-case eval-tagged-literal reassemble kv-seq]] - [clojure.walk :refer [walk postwalk]] + [aero.impl.walk :refer [postwalk]] #?@(:clj [[clojure.edn :as edn] [aero.impl.macro :as macro]] :cljs [[cljs.tools.reader.edn :as edn] diff --git a/src/aero/impl/walk.cljc b/src/aero/impl/walk.cljc new file mode 100644 index 0000000..3239ed2 --- /dev/null +++ b/src/aero/impl/walk.cljc @@ -0,0 +1,22 @@ +(ns aero.impl.walk) + +(defn- walk + [inner outer form] + (let [x (cond + (list? form) (outer (apply list (map inner form))) + #?@(:cljs [(map-entry? form) (outer (MapEntry. (inner (key form)) (inner (val form)) nil))] + :clj [(instance? clojure.lang.IMapEntry form) (outer (vec (map inner form)))]) + (seq? form) (outer (doall (map inner form))) + #?(:cljs (record? form) + :clj (instance? clojure.lang.IRecord form)) + (outer (reduce (fn [r x] (conj r (inner x))) form form)) + (coll? form) (outer (into (empty form) (map inner form))) + :else (outer form))] + (if #?(:cljs (implements? IWithMeta x) + :clj (instance? clojure.lang.IObj x)) + (with-meta x (merge (meta form) (meta x))) + x))) + +(defn postwalk + [f form] + (walk (partial postwalk f) f form)) diff --git a/test/aero/core_test.cljc b/test/aero/core_test.cljc index b896abe..3510c22 100644 --- a/test/aero/core_test.cljc +++ b/test/aero/core_test.cljc @@ -8,7 +8,7 @@ #?(:clj (:import [aero.core Deferred])) #?(:cljs (:require [aero.core :refer [read-config reader Deferred] :refer-macros [deferred]] [cljs.tools.reader :as edn] - [cljs.test :refer [deftest is testing]] + [cljs.test :refer [deftest is testing are]] [goog.object :as gobj] [goog.string :as gstring] goog.string.format @@ -231,3 +231,21 @@ config (#?(:cljs source-logging-push-back-reader :clj java.io.StringReader.) config-str)] (is (= "bar" (:y (read-config config)))))) + +(deftest meta-preservation-test + (are [ds] (= ds + (::foo + (meta + (read-config + (#?(:cljs source-logging-push-back-reader + :clj java.io.StringReader.) + (binding [*print-meta* true] + (pr-str (with-meta ds {::foo ds})))))))) + [] + {} + #{} + () + [1] + {:a :b} + #{:a :b} + '(1)))