Skip to content

Commit

Permalink
Merge pull request #49 from djblue/diff-meta
Browse files Browse the repository at this point in the history
Diff / preserve metadata on collections
  • Loading branch information
plexus authored Feb 16, 2024
2 parents e940bd1 + 2ad3dc1 commit 4828d93
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 29 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Added

- Diff / preserve metadata on collections

## Fixed

Varying key order in maps should produce a consistent diff (#47)
Expand Down
68 changes: 39 additions & 29 deletions src/lambdaisland/deep_diff2/diff_impl.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[clojure.set :as set]
[lambdaisland.clj-diff.core :as seq-diff]))

(declare diff diff-similar)
(declare diff diff-similar diff-meta)

(defrecord Mismatch [- +])
(defrecord Deletion [-])
Expand Down Expand Up @@ -92,40 +92,50 @@

(defn diff-seq [exp act]
(let [[rep del ins] (replacements (del+ins exp act))]
(->> exp
(diff-seq-replacements rep)
(diff-seq-deletions del)
(diff-seq-insertions ins)
(into []))))
(with-meta
(->> exp
(diff-seq-replacements rep)
(diff-seq-deletions del)
(diff-seq-insertions ins)
(into []))
(diff-meta exp act))))

(defn diff-set [exp act]
(into
(into #{}
(map (fn [e]
(if (contains? act e)
e
(->Deletion e))))
exp)
(map ->Insertion)
(remove #(contains? exp %) act)))
(with-meta
(into
(into #{}
(map (fn [e]
(if (contains? act e)
e
(->Deletion e))))
exp)
(map ->Insertion)
(remove #(contains? exp %) act))
(diff-meta exp act)))

(defn diff-map [exp act]
(let [exp-ks (set (keys exp))
act-ks (set (keys act))]
(reduce
(fn [m k]
(case [(contains? exp-ks k) (contains? act-ks k)]
[true false]
(assoc m (->Deletion k) (get exp k))
[false true]
(assoc m (->Insertion k) (get act k))
[true true]
(assoc m k (diff (get exp k) (get act k)))
(with-meta
(let [exp-ks (set (keys exp))
act-ks (set (keys act))]
(reduce
(fn [m k]
(case [(contains? exp-ks k) (contains? act-ks k)]
[true false]
(assoc m (->Deletion k) (get exp k))
[false true]
(assoc m (->Insertion k) (get act k))
[true true]
(assoc m k (diff (get exp k) (get act k)))
; `[false false]` will never occur because `k` necessarily
; originated from at least one of the two sets
))
{}
(set/union exp-ks act-ks))))
))
{}
(set/union exp-ks act-ks)))
(diff-meta exp act)))

(defn diff-meta [exp act]
(when (or (meta exp) (meta act))
(diff-map (meta exp) (meta act))))

(defn primitive? [x]
(or (number? x) (string? x) (boolean? x) (inst? x) (keyword? x) (symbol? x)))
Expand Down
9 changes: 9 additions & 0 deletions test/lambdaisland/deep_diff2/diff_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
(is (= []
(diff/diff [] [])))

(is (= {:meta true}
(meta (diff/diff ^:meta [] ^:meta []))))

(is (= [1 2 3]
(diff/diff (into-array [1 2 3]) [1 2 3])))

Expand Down Expand Up @@ -68,6 +71,9 @@
(is (= #{:a}
(diff/diff #{:a} #{:a})))

(is (= {:meta true}
(meta (diff/diff ^:meta #{} ^:meta #{}))))

(is (= #{(diff/->Insertion :a)}
(diff/diff #{} #{:a})))

Expand All @@ -80,6 +86,9 @@
(testing "maps"
(is (= {} (diff/diff {} {})))

(is (= {:meta true}
(meta (diff/diff ^:meta {} ^:meta {}))))

(is (= {:a (diff/->Mismatch 1 2)}
(diff/diff {:a 1} {:a 2})))

Expand Down

0 comments on commit 4828d93

Please sign in to comment.