Skip to content

Commit c46eb42

Browse files
committed
Basic protocol support for JS objects via mori.extend
1 parent 70f338e commit c46eb42

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

src/mori.cljs

+89-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ns mori
22
(:refer-clojure :exclude
3-
[count distinct empty first rest seq conj cons find nth last assoc dissoc
3+
[extend count distinct empty first rest seq conj cons find nth last assoc dissoc
44
get-in update-in assoc-in fnil disj pop peek hash get empty? reverse
55
take drop take-nth partition partition-all partition-by iterate
66
into merge merge-with subvec
@@ -275,6 +275,94 @@
275275
cljs.core.PersistentQueue
276276
cljs.core.PersistentQueueSeq)
277277

278+
;; =============================================================================
279+
;; JS Protocol support
280+
281+
(defn extend-to-iassociative [obj methods]
282+
(specify! obj
283+
IAssociative
284+
(-contains-key? [this k] (.call (aget methods "contains_key") this k))
285+
(-assoc [this k v] (.call (aget methods "assoc") this k v))))
286+
287+
(defn extend-to-icloneable [obj methods]
288+
(specify! obj
289+
ICloneable
290+
(-clone [this] (.call (aget methods "clone") this))))
291+
292+
(defn extend-to-icollection [obj methods]
293+
(specify! obj
294+
ICollection
295+
(-conj [this o] (.call (aget methods "conj") this o))))
296+
297+
(defn extend-to-icounted [obj methods]
298+
(specify! obj
299+
ICounted
300+
(-count [this] (.call (aget methods "count") this))))
301+
302+
(defn extend-to-iencodeclojure [obj methods]
303+
(specify! obj
304+
IEncodeClojure
305+
(-js->clj [this options] (.call (aget methods "toClj") this options))))
306+
307+
(defn extend-to-iencodejs [obj methods]
308+
(specify! obj
309+
IEncodeJS
310+
(-clj->js [this] (.call (aget methods "toJS") this))))
311+
312+
(defn extend-to-iequiv [obj methods]
313+
(specify! obj
314+
IEquiv
315+
(-equiv [this obj] (.call (aget methods "equiv") this obj))))
316+
317+
(defn extend-to-ihash [obj methods]
318+
(specify! obj
319+
IHash
320+
(-hash [this] (.call (aget methods "hash") this))))
321+
322+
(defn extend-to-ikvreduce [obj methods]
323+
(specify! obj
324+
IKVReduce
325+
(-kv-reduce [this f init] (.call (aget methods "reduce_kv") this f init))))
326+
327+
(defn extend-to-ilookup [obj methods]
328+
(specify! obj
329+
ILookup
330+
(-lookup [this k] (-lookup this k nil))
331+
(-lookup [this k not-found] (.call (aget methods "lookup") this k not-found))))
332+
333+
(defn extend-to-imap [obj methods]
334+
(specify! obj
335+
IMap
336+
(-dissoc [this k] (.call (aget methods "dissoc") this k))))
337+
338+
(defn extend-to-iseq [obj methods]
339+
(specify! obj
340+
ISeq
341+
(-first [this] (.call (aget methods "first") this))
342+
(-rest [this] (.call (aget methods "rest") this))))
343+
344+
(defn extend-to-iseqable [obj methods]
345+
(specify! obj
346+
ISeqable
347+
(-seq [this] (.call (aget methods "seq") this))))
348+
349+
(defn ^:export extend [protocol-name obj methods]
350+
(case protocol-name
351+
"IAssociative" (extend-to-iassociative obj methods)
352+
"ICloneable" (extend-to-icloneable obj methods)
353+
"ICollection" (extend-to-icollection obj methods)
354+
"ICounted" (extend-to-icounted obj methods)
355+
"IEncodeClojure" (extend-to-iencodeclojure obj methods)
356+
"IEncodeJS" (extend-to-iencodejs obj methods)
357+
"IEquiv" (extend-to-iequiv obj methods)
358+
"IHash" (extend-to-ihash obj methods)
359+
"IKVReduce" (extend-to-ikvreduce obj methods)
360+
"ILookup" (extend-to-ilookup obj methods)
361+
"IMap" (extend-to-imap obj methods)
362+
"ISeq" (extend-to-iseq obj methods)
363+
"ISeqable" (extend-to-iseqable obj methods)
364+
(throw (js/Error. (str "Cannot extend to " protocol-name)))))
365+
278366
;; =============================================================================
279367
;; Closure hacks so we get exported ES6 Map/Set interface on collections
280368
;; Following functions are NOT a part of the API

0 commit comments

Comments
 (0)