Created
November 5, 2014 23:03
-
-
Save hadronzoo/f5e21a6290cfb714070e to your computer and use it in GitHub Desktop.
Clojure MapCursor
This file contains hidden or 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 cursors.core | |
| (:refer-clojure :exclude [swap! reset!])) | |
| (defprotocol ICursor | |
| (-path [c]) | |
| (-state [c])) | |
| (defprotocol IToCursor | |
| (-to-cursor [c state path])) | |
| (defn swap! [cursor f & args] | |
| (let [state (-state cursor) | |
| path (-path cursor)] | |
| (-> (clojure.core/swap! state update-in path | |
| #(apply f (list* % args))) | |
| (get-in path) | |
| (-to-cursor state path)))) | |
| (defn reset! [cursor newval] | |
| (swap! cursor (fn [_] newval))) | |
| (defn cursor? [c] | |
| (satisfies? ICursor c)) | |
| (declare ->MapCursor) | |
| (extend-protocol IToCursor | |
| java.lang.Object | |
| (-to-cursor [this state path] this) | |
| clojure.lang.APersistentMap | |
| (-to-cursor [this state path] | |
| (->MapCursor this state path))) | |
| (deftype MapCursor [value state path] | |
| ICursor | |
| (-path [_] path) | |
| (-state [_] state) | |
| IToCursor | |
| (-to-cursor [this state path] this) | |
| clojure.lang.IDeref | |
| (deref [this] | |
| (get-in @state path)) | |
| clojure.lang.MapEquivalence | |
| clojure.lang.IPersistentCollection | |
| (equiv [this x] (.equiv value x)) | |
| (cons [this o] | |
| (-> (if (map? o) | |
| (reduce #(apply assoc %1 %2) this o) | |
| (if-let [[k v] (seq o)] | |
| (assoc this k v) | |
| this)) | |
| (-to-cursor state path))) | |
| clojure.lang.IObj | |
| (withMeta [this mta] | |
| (-to-cursor (.withMeta value mta) state path)) | |
| (meta [this] (meta value)) | |
| clojure.lang.Counted | |
| (count [this] (count value)) | |
| clojure.lang.Seqable | |
| (seq [this] | |
| (when (pos? (count value)) | |
| (map (fn [[k v]] | |
| (clojure.lang.MapEntry. k (-to-cursor v state (conj path k)))) | |
| value))) | |
| ^{:min-version "1.4.0"} | |
| clojure.core.protocols.CollReduce | |
| ^{:min-version "1.4.0"} | |
| (coll-reduce [this f] (.coll-reduce value f)) | |
| ^{:min-version "1.4.0"} | |
| (coll-reduce [this f val] (.coll-reduce value f val)) | |
| clojure.lang.IHashEq | |
| (hasheq [this] (.hasheq value)) | |
| Object | |
| (hashCode [this] (.hashCode value)) | |
| (equals [this x] (.equals value x)) | |
| (toString [this] (.toString value)) | |
| clojure.lang.ILookup | |
| (valAt [this k] (.valAt this k nil)) | |
| (valAt [this k default] | |
| (let [v (.valAt value k default)] | |
| (if-not (= v default) | |
| (-to-cursor v state (conj path k)) | |
| default))) | |
| clojure.lang.Associative | |
| (containsKey [this k] (.containsKey value k)) | |
| (entryAt [this k] (.valAt this k)) | |
| (assoc [this k v] | |
| (-to-cursor (assoc value k v) state path)) | |
| (empty [this] | |
| (-to-cursor (empty value) state path)) | |
| java.util.Map | |
| (get [this k] (.valAt this k)) | |
| (isEmpty [this] (.isEmpty value)) | |
| (size [this] (.size value)) | |
| (keySet [this] (.keySet value)) | |
| (put [_ _ _] | |
| (throw (UnsupportedOperationException.))) | |
| (putAll [_ _] | |
| (throw (UnsupportedOperationException.))) | |
| (clear [_] | |
| (throw (UnsupportedOperationException.))) | |
| (remove [_ _] | |
| (throw (UnsupportedOperationException.))) | |
| (values [this] (.values value)) | |
| (entrySet [this] (.entrySet value)) | |
| clojure.lang.IPersistentMap | |
| (assocEx [this k v] | |
| (assoc this k v)) | |
| (without [this k] | |
| (-to-cursor (dissoc value k) state path)) | |
| clojure.lang.IFn | |
| (invoke [this k] | |
| (.valAt this k)) | |
| (invoke [this k default] | |
| (.valAt this k default))) | |
| (prefer-method print-method clojure.lang.IPersistentMap clojure.lang.IDeref) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment