Last active
March 10, 2016 14:47
-
-
Save bendlas/44d000a197c9e765d05b to your computer and use it in GitHub Desktop.
block scoping for generating ids in edn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require '[clojure.edn :as edn] '[clojure.zip :as zip] '[clojure.pprint :as pp]) | |
(defrecord Kwid [kw]) | |
(defrecord Dbid [part id]) | |
(defn empty [o] ;; overwrite clojure's builtin, see http://dev.clojure.org/jira/browse/CLJ-1893 | |
(if (instance? clojure.lang.MapEntry o) | |
[] (clojure.core/empty o))) | |
(def coll-zipper (partial zip/zipper coll? seq #(into (empty %1) %2))) | |
(defn replace-kwids [data] | |
(let [part (gensym "part-")] | |
(loop [dz (coll-zipper data) | |
seen {}] | |
(let [v (zip/node dz)] | |
(if (instance? Kwid v) | |
(if-let [id (get seen (:kw v))] | |
(recur (zip/replace dz id) seen) | |
(let [next-id (->Dbid part (inc (apply max -1 (map :id (vals seen)))))] | |
(recur (zip/replace dz next-id) | |
(assoc seen (:kw v) next-id)))) | |
(if (zip/end? dz) | |
(zip/root dz) | |
(recur (zip/next dz) seen))))))) | |
(def read-testdata (partial edn/read-string | |
{:readers {'fresh replace-kwids | |
'kwid ->Kwid | |
'concat (partial apply concat)}})) | |
(pp/pprint | |
(read-testdata | |
"#concat | |
[#fresh [{:db/id #kwid :one | |
:data \"this is one/one\" | |
:link/to #kwid :two} | |
{:db/id #kwid :two | |
:data \"this is one/two\" | |
:link/to #kwid :one}] | |
#fresh [{:db/id #kwid :one | |
:data \"this is two/one\" | |
:link/to #kwid :two} | |
{:db/id #kwid :two | |
:data \"this is two/two\" | |
:link/to #kwid :one}]]")) | |
(comment ;; this should print (modulo gensyms): | |
({:link/to {:part part-45, :id 0}, | |
:db/id {:part part-45, :id 1}, | |
:data "this is one/one"} | |
{:link/to {:part part-45, :id 1}, | |
:db/id {:part part-45, :id 0}, | |
:data "this is one/two"} | |
{:link/to {:part part-46, :id 0}, | |
:db/id {:part part-46, :id 1}, | |
:data "this is two/one"} | |
{:link/to {:part part-46, :id 1}, | |
:db/id {:part part-46, :id 0}, | |
:data "this is two/two"})) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment