-
Notifications
You must be signed in to change notification settings - Fork 1
/
zipper.clj
34 lines (28 loc) · 1.17 KB
/
zipper.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(ns ez-database.query.zipper
(:require [clojure.zip :as zip])
(:import [clojure.lang IPersistentVector IPersistentMap IPersistentList ISeq]))
(defmulti branch? class)
(defmethod branch? :default [_] false)
(defmethod branch? IPersistentVector [v] true)
(defmethod branch? IPersistentMap [m] true)
(defmethod branch? IPersistentList [l] true)
(defmethod branch? ISeq [s] true)
(defmulti seq-children class)
(defmethod seq-children IPersistentVector [v] v)
(defmethod seq-children IPersistentMap [m] (mapv identity m))
(defmethod seq-children IPersistentList [l] l)
(defmethod seq-children ISeq [s] s)
(defmulti make-node (fn [node children] (class node)))
(defmethod make-node IPersistentVector [v children]
(vec children))
(defmethod make-node IPersistentMap [m children]
(into {} children))
(defmethod make-node IPersistentList [_ children]
children)
(defmethod make-node ISeq [node children]
(apply list children))
(prefer-method make-node IPersistentList ISeq)
(defn zipper [node]
(zip/zipper branch? seq-children make-node node))
(prefer-method branch? clojure.lang.IPersistentList clojure.lang.ISeq)
(prefer-method seq-children clojure.lang.IPersistentList clojure.lang.ISeq)