Last active
September 23, 2015 18:25
-
-
Save KeeganMyers/311fc4fa80222a693d18 to your computer and use it in GitHub Desktop.
traverse
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
(ns arc.shared.traverse | |
(:require | |
#?@(:clj [[arc.server.commandHandler.dataMapper | |
:as m] | |
[arc.shared.util :as u] | |
[schema.core :as s]] | |
:cljs [[cljs-uuid-utils.core :as uuid] | |
[arc.shared.util :as u] | |
[schema.core :as s | |
:include-macros true]]))) | |
#?(:clj | |
(defn make-id-queue [id-queue] | |
(conj id-queue (m/id-hash))) | |
:cljs | |
(defn make-id-queue [id-queue] | |
(conj id-queue (uuid/make-random-uuid)))) | |
(s/defn last-id :- u/maybeString [elem :- s/Any] | |
(last (:id (meta elem)))) | |
(defprotocol Traversable | |
(append-meta [this id-queue]) | |
(update-elem [this id f])) | |
(extend-type | |
#?(:clj clojure.lang.PersistentArrayMap | |
:cljs cljs.core/PersistentArrayMap) | |
Traversable | |
(append-meta [this id-queue] | |
(let [curr-queue (make-id-queue id-queue)] | |
(with-meta (into {} (for | |
[[k v] this] {k (append-meta v curr-queue)})) | |
{:id curr-queue}))) | |
(update-elem [this id-queue f] | |
(cond | |
(and (= (count id-queue) 1 ) | |
(= (last-id this) (peek id-queue))) | |
(with-meta (into {} (f this)) (meta this)) | |
(and (> (count id-queue) 1) | |
(= (last-id this) (peek id-queue))) | |
(let [lim-id-queue (pop id-queue)] | |
(with-meta (into {} (for [[k v ] this] | |
{k (update-elem v lim-id-queue f) })) (meta this))) | |
:else | |
(with-meta this (meta this) )))) | |
(extend-type | |
#?(:clj clojure.lang.PersistentHashSet | |
:cljs cljs.core/PersistentHashSet) | |
Traversable | |
(append-meta [this id-queue] | |
(let [curr-queue (make-id-queue id-queue)] | |
(with-meta (set | |
(map #(append-meta % curr-queue) | |
this)) | |
{:id curr-queue}))) | |
(update-elem [this id-queue f] | |
(cond | |
(and (= (count id-queue) 1 ) | |
(= (last-id this) (peek id-queue))) | |
(with-meta (set (f this)) (meta this)) | |
(and (> (count id-queue) 1) | |
(= (last-id this) (peek id-queue))) | |
(let [lim-id-queue (pop id-queue)] | |
(with-meta (set (map #(update-elem % lim-id-queue f) | |
this)) (meta this))) | |
:else | |
(with-meta this (meta this))))) | |
(extend-type | |
#?(:clj clojure.lang.PersistentVector | |
:cljs cljs.core/PersistentVector) | |
Traversable | |
(append-meta [this queue] | |
(let [curr-queue (make-id-queue queue)] | |
(with-meta (vec | |
(map #(append-meta % curr-queue) | |
this)) | |
{:id curr-queue}))) | |
(update-elem [this id-queue f] | |
(cond | |
(and (= (count id-queue) 1 ) | |
(= (last-id this) (peek id-queue))) | |
(with-meta (vec (f this)) (meta this)) | |
(and (> (count id-queue) 1) | |
(= (last-id this) (peek id-queue))) | |
(let [lim-id-queue (pop id-queue)] | |
(with-meta (vec (map #(update-elem % lim-id-queue f) | |
this)) (meta this))) | |
:else | |
(with-meta this (meta this))))) | |
(extend-type | |
#?(:clj Object | |
:cljs default) | |
Traversable | |
(append-meta [obj id-queue] | |
obj) | |
(update-elem [obj id-queue f] | |
obj)) | |
(s/defn add-meta-id :- s/Any [coll :- s/Any] | |
(let [q (u/queue)] | |
(append-meta coll q))) | |
(s/defn update-by-elem :- s/Any [coll :- s/Any elem :- s/Any f :- s/Any] | |
(let [id-queue (:id (meta elem))] | |
(with-meta (update-elem coll id-queue f) (meta coll)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment