60 lines
2.0 KiB
Clojure
60 lines
2.0 KiB
Clojure
(ns emptyhead.idea.crud
|
|
"Functions for Creating, Updating and Deleting ideas.
|
|
The 'R' in 'CRUD' is implemented by [[emptyhead.idea.protocol/value]]."
|
|
(:require [emptyhead.idea.state :refer [state]]
|
|
[emptyhead.idea.property :as prop]
|
|
[emptyhead.idea.protocol :as prtc]))
|
|
|
|
(defn- register-idea!
|
|
"Helper function to scaffold an 'empty' idea."
|
|
[ref]
|
|
(swap! state assoc-in [ref :_meta :_properties] #{})
|
|
(swap! state assoc-in [ref :_meta :_reference] ref)
|
|
ref)
|
|
|
|
(defn swap-idea!
|
|
"Swap data inside `idea` with given `data`.
|
|
Returns a reference to `idea`."
|
|
[idea data]
|
|
(swap! state assoc
|
|
(prtc/reference idea)
|
|
(merge data {:_meta (prtc/val-fn :_meta idea)}))
|
|
(prtc/reference idea))
|
|
|
|
(defn extend-idea!
|
|
"Merge `data` into state of `idea`.
|
|
Returns a reference to `idea`."
|
|
[idea data]
|
|
(swap! state assoc (prtc/reference idea) (prtc/val-fn merge idea data))
|
|
(prtc/reference idea))
|
|
|
|
(defn mutate-idea!
|
|
"Evaluate `fun` on `idea` with optional extra `args`, then replace `idea` by the result.
|
|
Returns a reference to `idea`."
|
|
[fun idea & args]
|
|
(swap-idea! idea (prtc/val-fn fun idea args))
|
|
(prtc/reference idea))
|
|
|
|
(defn forget-idea!
|
|
"Delete `idea` from the state.
|
|
Returns a copy of the `idea`."
|
|
[idea]
|
|
(let [val (prtc/value idea)]
|
|
(apply prop/remove-property! idea (prop/properties idea))
|
|
(prtc/ref-fn #(swap! state dissoc %) idea)
|
|
(prtc/copy val)))
|
|
|
|
(defn have-idea!
|
|
"Instantiate up to `count` new ideas, optionally prefixing reference symbol with `prefix`.
|
|
Additionally allows you to immediately attach `properties` and `data`.
|
|
Returns a single idea or a list of ideas depending on whether `count` was given."
|
|
[& {:keys [prefix count properties data]
|
|
:or {count 1 prefix "idea_" properties []}}]
|
|
(let [fun #(register-idea! (gensym prefix))
|
|
ideas (take count (repeatedly fun))]
|
|
(run! #(apply prop/register-property! % properties) ideas)
|
|
(when data (run! #(extend-idea! % data) ideas))
|
|
(if (= count 1)
|
|
(first ideas)
|
|
ideas)))
|