Skip to content

Commit

Permalink
Add profile and deprofile functions
Browse files Browse the repository at this point in the history
  • Loading branch information
weavejester committed Sep 23, 2024
1 parent 69e906e commit 58a7d0e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
36 changes: 35 additions & 1 deletion src/integrant/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@
[x]
(satisfies? RefLike x))

(defrecord Profile [])

(defn profile
"Create a map of profile keys to values. See: `expand`."
[m]
(map->Profile m))

(defn profile?
"Return true if its argument is a profile."
[x]
(instance? Profile x))

(defn- depth-search [pred? coll]
(filter pred? (tree-seq coll? seq coll)))

Expand Down Expand Up @@ -163,7 +175,10 @@
(defn- reverse-dependent-keys [config keys]
(reverse (find-keys config keys dep/transitive-dependents-set)))

(def ^:private default-readers {'ig/ref ref, 'ig/refset refset})
(def ^:private default-readers
{'ig/ref ref
'ig/refset refset
'ig/profile profile})

(defn read-string
"Read a config from a string of edn. Refs may be denotied by tagging keywords
Expand Down Expand Up @@ -476,6 +491,25 @@
(reduce-kv (fn [m k v] (assoc m k (if (keyset k) (prep-key k v) v)))
{} config))))

(defn- missing-profile-key-exception [profile keys]
(ex-info (str "Missing a valid key for profile")
{:reason ::missing-profile-key
:profile profile
:profile-keys keys}))

(defn- deprofile-1 [profile keys]
(if-some [key (first (filter #(contains? profile %) keys))]
(get profile key)
(throw (missing-profile-key-exception profile keys))))

(defn deprofile
"Find all profiles in a collection, then turns them into values using an
ordered collection of profile keys. The profile keys will be tried on each
profile in order until the profile returns a match. If there is no match, a
exception will be thrown."
[coll profile-keys]
(walk/postwalk #(if (profile? %) (deprofile-1 % profile-keys) %) coll))

(defn- normal-map? [x]
(and (map? x) (not (reflike? x))))

Expand Down
13 changes: 13 additions & 0 deletions test/integrant/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,16 @@
(is (some? cause))
(is (= (#?(:clj .getMessage :cljs ex-message) cause) "Testing"))
(is (= (ex-data cause) {:reason ::test}))))))

(deftest profile-test
(is (= (ig/deprofile (ig/profile {:a 1}) [:a])
1))
(is (= (ig/deprofile (ig/profile {:a 1 :b 2}) [:b :a])
2))
(is (= (ig/deprofile {::x (ig/profile {:a 1 :b 2})
::y (ig/profile {:b 1 :a 2})}
[:a])
{::x 1, ::y 2}))
(is (= (ig/deprofile {::x [1 2 (ig/profile {:a 1, :b 2, :c 3})]}
[:c :a])
{::x [1 2 3]})))

0 comments on commit 58a7d0e

Please sign in to comment.