/
navigation.cljc
47 lines (43 loc) · 1.61 KB
/
navigation.cljc
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
35
36
37
38
39
40
41
42
43
44
45
46
47
(ns flanders.navigation
(:require [clojure.zip :as z]
[flanders.predicates :as fp]
[flanders.utils :as fu]))
(defn- keyword-key
"Given a zip location of a KeywordType, if it is the :key of a
MapEntry, and if it must equal a specific keyword value, then return
that value."
[kw-loc]
(when-let [{:keys [open? values]} (some-> kw-loc fp/keyword fp/key z/node)]
(when (and (not open?)
(= 1 (count values)))
(first values))))
(defn- type-value
"Given a zip location of a leaf node, it if must equal a specific
value, then return that value."
[type-loc]
(when-let [{:keys [open? values]} (some-> type-loc fp/leaf z/node)]
(when (and (not open?)
(= 1 (count values)))
(first values))))
(defn find-entry-loc
"Given a zip location pointing at a MapType, find the first
entry-location who's KeywordType key matches a given keyword."
[map-loc kw-to-match]
(last ;; there may be duplicates and last-match is preferred
(filter (fn [entry-loc]
(when-let [key-loc (some-> entry-loc fp/entry z/down)]
(when (= kw-to-match
(keyword-key key-loc))
entry-loc)))
(some-> map-loc z/down fu/right-loc-seq))))
(defn find-entry-value
"Given a zip location pointing at a MapType, find the first
entry-location who's KeywordType key matches a given keyword, and
return the entry's type value if the type value must equal a single
specific value."
[map-loc key-kw]
(some-> map-loc
(find-entry-loc key-kw)
z/down
z/rightmost
type-value))