Skip to content

Instantly share code, notes, and snippets.

@KeeganMyers
Last active September 23, 2015 18:25
Show Gist options
  • Save KeeganMyers/311fc4fa80222a693d18 to your computer and use it in GitHub Desktop.
Save KeeganMyers/311fc4fa80222a693d18 to your computer and use it in GitHub Desktop.
traverse
(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