Skip to content

Commit b44b0c6

Browse files
committed
Add docstrings
1 parent cf1c952 commit b44b0c6

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Cljfx dev tools

src/cljfx/dev.clj

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,30 @@
11
(ns cljfx.dev
2+
"Helpers for cljfx app development that shouldn't be included into production
3+
4+
You can get help for existing lifecycles and props by using help fn:
5+
6+
(cljfx.dev/help)
7+
;; prints information about all cljfx lifecycles including :label
8+
(cljfx.dev/help :label)
9+
;; prints information about label and its props including :graphic
10+
(cljfx.dev/help :label :graphic)
11+
;; prints information about :graphic prop of a label
12+
13+
You can also add cljfx component validation that greatly improves error
14+
messages using cljfx.dev/type->lifecycle (or cljfx.dev/wrap-type->lifecycle):
15+
16+
(fx/create-component
17+
{:fx/type :stage
18+
:scene {:fx/type :scene
19+
:root {:fx/type :label
20+
:text true}}}
21+
{:fx.opt/type->lifecycle cljfx.dev/type->lifecycle})
22+
;; Execution error (ExceptionInfo) at cljfx.dev/ensure-valid-desc (validation.clj:62).
23+
;; Invalid cljfx description of :stage type:
24+
;; true - failed: string? in [:scene :root :text]
25+
;;
26+
;; Cljfx component stack:
27+
;; :stage"
228
(:require [cljfx.lifecycle :as lifecycle]
329
[cljfx.api :as fx]
430
[clojure.spec.alpha :as s]
@@ -72,9 +98,28 @@
7298
(s/and map? valid-fx-type? desc->spec))
7399

74100
(defn register-props!
101+
"Associate props description with some id
102+
103+
Args:
104+
id prop identifier, either keyword or symbol
105+
parent semantical parent id of the prop map, meaning props with the id
106+
should also accept props with parent id
107+
props a map from keyword to prop description, which is a map with
108+
a :type key that can be either:
109+
- symbol of a class name
110+
- keyword that defines a corresponding spec form by extending
111+
keyword-prop->spec-form multi-method"
75112
([id props]
76113
(register-props! id nil props))
77114
([id parent props]
115+
{:pre [(ident? id)
116+
(or (nil? parent) (ident? parent))
117+
(or (nil? props)
118+
(and (map? props)
119+
(every? (fn [[k v]]
120+
(and (keyword? k)
121+
(contains? v :type)))
122+
props)))]}
78123
(swap!
79124
registry
80125
(fn [registry]
@@ -94,8 +139,19 @@
94139
(assoc id->props id props))))))
95140
id))
96141

97-
(defn ^{:arglists '([id & {:keys [spec of]}])} register-type! [id & {:as opts}]
98-
{:pre [(ident? id)]}
142+
(defn register-type!
143+
"Associate cljfx type description with some id
144+
145+
Optional kv-args:
146+
:spec a spec to use when validating props of components with the id
147+
:of component instance class identifier, either:
148+
- symbol of a class name, e.g. javafx.scene.Node
149+
- keyword of a prop that hold another cljfx description that
150+
defines component instance class, e.g. :desc"
151+
[id & {:keys [spec of] :as opts}]
152+
{:pre [(ident? id)
153+
(or (nil? of)
154+
(ident? of))]}
99155
(swap! registry update :types assoc id (assoc opts :id id))
100156
id)
101157

@@ -109,7 +165,12 @@
109165

110166
(defmulti keyword-prop->spec-form :type)
111167

112-
(defn prop->spec-form [prop]
168+
(defn prop->spec-form
169+
"Convert prop type config to spec form (i.e. clojure form that evals to spec)
170+
171+
You can extend prop type configs by adding more implementations to
172+
keyword-prop->spec-form multimethod"
173+
[prop]
113174
(let [{:keys [type]} prop]
114175
(if (symbol? type)
115176
`(instance-of ~type)
@@ -132,7 +193,24 @@
132193
:opt-un ~(into [] (map k->spec-kw) (sort ks)))
133194
(only-keys ~ks))))))
134195

135-
(defn register-composite! [id & {:keys [parent props of req]}]
196+
(defn register-composite!
197+
"Associate a composite lifecycle type description with some id
198+
199+
Required kv-args:
200+
:of symbol of a component instance class
201+
202+
Optional kv-args:
203+
:parent semantic parent id of a lifecycle, meaning lifecycle with the id
204+
should also accept all props of parent id
205+
:props a map from keyword to prop description, which is a map with
206+
a :type key that can be either:
207+
- symbol of a class name
208+
- keyword that defines a corresponding spec form by extending
209+
keyword-prop->spec-form multi-method
210+
:req required props on the component, either:
211+
- a vector of prop keywords (all are required)
212+
- a set of vectors of prop keywords (either vector is required)"
213+
[id & {:keys [parent props of req]}]
136214
{:pre [(symbol? of)
137215
(every? simple-keyword? (keys props))]}
138216
(register-props! id parent props)
@@ -241,6 +319,18 @@
241319
(load "dev/validation")
242320

243321
(defn wrap-type->lifecycle
322+
"Wrap type->lifecycle used in the cljfx UI app with improved error messages
323+
324+
Wrapped lifecycle performs spec validation of cljfx descriptions that results
325+
in better error messages shown when cljfx descriptions are invalid.
326+
327+
Additionally, exceptions thrown during cljfx lifecycle show a cljfx component
328+
stack to help with debugging.
329+
330+
Args:
331+
type->lifecycle the type->lifecycle fn used in opts of your app
332+
type->id custom type->id if you need a way to get id from your
333+
custom lifecycles"
244334
([type->lifecycle]
245335
(wrap-type->lifecycle type->lifecycle *type->id*))
246336
([type->lifecycle type->id]
@@ -249,6 +339,8 @@
249339
(f type type->lifecycle type->id)))))
250340

251341
(def type->lifecycle
342+
"Default type->lifecycle that can be used in the cljfx UI app to improve error
343+
messages"
252344
(wrap-type->lifecycle (some-fn fx/keyword->lifecycle fx/fn->lifecycle)))
253345

254346
;; next steps:

0 commit comments

Comments
 (0)