Skip to content

Instantly share code, notes, and snippets.

@noprompt
Created June 28, 2016 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noprompt/3f1e659756c06c362114ca101dd0d8b4 to your computer and use it in GitHub Desktop.
Save noprompt/3f1e659756c06c362114ca101dd0d8b4 to your computer and use it in GitHub Desktop.
(ns state-box)
(defprotocol IGetState
(-get-state [state key]))
(defprotocol IPutState
(-put-state [state key value]))
(deftype ImmutableBox [get-state put-state state]
IGetState
(-get-state [this key]
(get-state state key))
IPutState
(-put-state [this key value]
(ImmutableBox. get-state put-state (put-state state key value))))
(deftype MutableBox [get-state put-state state]
IGetState
(-get-state [this key]
((. this get-state) (deref state) key))
IPutState
(-put-state [this key value]
(swap! state (. this put-state) key value)
this))
(defn immutable-box
[get-state put-state state]
(ImmutableBox. get-state put-state state))
(defn mutable-box
[get-state put-state initial-state]
(MutableBox. get-state put-state (atom initial-state)))
(defmulti get-state-demo
(fn [state [key]]
key)
:default ::key-not-found)
(defmethod get-state-demo :users/all
[state _]
(get state :users []))
(defmethod get-state-demo :users/by-id
[state [_ {id :id}]]
(let [users (get-state-demo state [:users/all])]
(for [user users
:when (= (get user :id)
id)]
user)))
(defmulti put-state-demo
(fn [state [key] value]
key)
:default ::key-not-found)
(defmethod put-state-demo :users/create
[state [key parameters] value]
(let [last-user-id (-> (get-state-demo state [:users/all])
(last)
(get :id 0)
(inc))
new-users (map (fn [user-parameters id]
(assoc user-parameters :id id))
value
(range last-user-id Float/POSITIVE_INFINITY))]
(update state :users into new-users)))
(comment
(let [mbox (mutable-box get-state-demo put-state-demo {})]
;; Write a couple of users to our box.
(-put-state mbox [:users/create] [{:name "Bob"} {:name "Alice"}])
;; => #object[crede.core.MutableBox 0x6c74e120 "crede.core.MutableBox@6c74e120"]
;; Get them back out.
(-get-state mbox [:users/all])
;; => ({:name "Alice", :id 2} {:name "Bob", :id 1})
;; Get one by id.
(-get-state mbox [:users/by-id {:id 2}])))
;; => ({:name "Alice", :id 2})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment