diff --git a/src/swark/authom.cljc b/src/swark/authom.cljc index 81a18a5..c5064e1 100644 --- a/src/swark/authom.cljc +++ b/src/swark/authom.cljc @@ -1,4 +1,6 @@ (ns swark.authom + {:added "0.1.3" + :doc "(Re)store auth related stuff in clojure metadata."} (:require [swark.core :refer [try?]])) ;; swark.authom - Atomic authorisation made easy diff --git a/src/swark/core.cljc b/src/swark/core.cljc index 9816b69..7dffd24 100644 --- a/src/swark/core.cljc +++ b/src/swark/core.cljc @@ -1,6 +1,5 @@ (ns swark.core - (:require [clojure.string :as str]) - (:import [clojure.lang Named])) + (:require [clojure.string :as str])) ;; SWiss ARmy Knife - Your everyday clojure toolbelt! ;; Copyright 2024 - Stan Verberkt (verberktstan@gmail.com) @@ -9,8 +8,13 @@ ;; Regarding collections (defn key-by - "Returns a map with all items in collection `coll` keyed by the value returned by `(f item)` - When `(f item)` returns a falsey value, it is NOT included in the resulting map." + {:added "0.1.0" + :arglist '([f coll]) + :doc "Returns a map containing (all) items in coll, associated by the + return value of (f val). When the key is logical false, it is not included in + the returned map. + `(key-by count [[:a] [:b :c]]) => {1 [:a] 2 [:b :c]}`" + :static true} [f coll] (when coll (-> f ifn? assert) @@ -24,21 +28,27 @@ ;; Regarding maps (defn map-vals - "Returns map `m` with function `f` applied to all its values." - [f m] - (when m + {:added "0.1.0" + :arglist '([f item]) + :doc "Returns item with f mapped across it's values. + `(map-vals inc {:a 1}) => {:a 2}`" + :static true} + [f item] + (when item (-> f ifn? assert) - (-> m map? assert) - (->> m + (-> item map? assert) + (->> item (map (juxt key (comp f val))) (into {})))) (defn filter-keys - [map pred] {:added "0.1.3" :arglists '([map pred]) - :doc "Returns a map containing only those entries in map whose key return logical true on evaluation of (pred key)." + :doc "Returns a map containing only those entries in map whose key return + logical true on evaluation of (pred key). + `(filter-keys {:a 1 \"b\" 2} keyword?) => {:a 1}`" :static true} + [map pred] (cond->> map pred (filter (comp pred key)) map seq @@ -48,8 +58,12 @@ ;; Try and return nil when something is thrown (defn try? - "Returns the result of (apply f args). When any error or exception is trown, - returns `nil`." + {:added "0.1.3" + :arglists '([f & args]) + :doc "Returns the result of (apply f args). When any error or exception is + thrown, simply returns nil instead. + `(try? inc nil) => nil`" + :static true} [f & args] (try (apply f args) @@ -58,7 +72,10 @@ (defn select-namespaced {:added "0.1.3" :arglist '([map] [map ns]) - :doc "Returns a map containing only those entries in map whose keys' namespace match ns. When ns is nil, returns a map containing only non-namespaced keys." + :doc "Returns a map containing only those entries in map whose keys' + namespace match ns. When ns is nil, returns a map containing only + non-namespaced keys. + `(select-namespaced {::test 1 :test 2} (namespace ::this)) => {::test 1}`" :static true} ([map] (select-namespaced map nil)) @@ -116,20 +133,28 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Minimalistic spec + +(defn- check [predicate input] + {::predicate predicate ::input input ::result (predicate input)}) + (defn invalid-map? - "Returns nil if map `input` is valid according to map `spec`. - When `input` is nil, returns {::input nil}. - When `input` is invalid, returns a map with a report on why it is invalid." + {:added "0.1.1" + :arglist '([spec input]) + :doc "Returns nil if input is valid according to spec. When input is invalid, + returns a map reporting how it is invalid. When input is nil, returns the + special keyword ::nil. + `(valid-map? {:a string?} {:a 12}) ≠> {::predicate string? ::input 12 ::result false}`" + :static true} [spec input] (-> spec map? (assert "Spec should be a map!")) (assert (->> spec vals (every? ifn?)) "All vals in spec should implement IFn!") (some-> input map? (assert "Input should be a map!")) - (case input - nil {::input input} ; Explicit inform that input is nil + (if (nil? input) + ::nil ; Explicit inform that input is nil (some->> input - (merge-with (fn [predicate input] {::predicate predicate ::input input ::result (predicate input)}) spec) - (remove (comp ::result val)) - seq - (into {})))) + (merge-with check spec) + (remove (comp ::result val)) + seq + (into {})))) (def valid-map? (complement invalid-map?)) \ No newline at end of file diff --git a/src/swark/eav.cljc b/src/swark/eav.cljc index a1af89f..d5c5c2f 100644 --- a/src/swark/eav.cljc +++ b/src/swark/eav.cljc @@ -1,4 +1,6 @@ -(ns swark.eav) +(ns swark.eav + {:added "0.1.3" + :doc "Serialize and parse data as entity-atteibute-value rows."}) ;; Storing data as Entity / Attribute / Value rows diff --git a/test/swark/core_test.clj b/test/swark/core_test.clj index a9cee82..e312ba0 100644 --- a/test/swark/core_test.clj +++ b/test/swark/core_test.clj @@ -83,8 +83,8 @@ (t/are [result spec input] (= result (sut/invalid-map? spec input)) nil {:id nat-int?} {:id 0} ; Valid, so `nil` is returned {:id report} {:id nat-int?} {:id -1} ; Invalid, so a set of invalid keys is returns - {::sut/input nil} {} nil ; Nil input, so ::swark/nil is returned - {::sut/input nil} {:id nat-int?} nil) + ::sut/nil {} nil ; Nil input, so ::swark/nil is returned + ::sut/nil {:id nat-int?} nil) (t/are [msg spec input] (thrown-with-msg? AssertionError msg (sut/valid-map? spec input)) #"Spec should be a map!" nil {:id -1} #"All vals in spec should implement IFn" {:id "not IFn"} {:id -1} ; Spec