001 (ns vl-data-insert.utils
002 ^{:author "wactbprot"
003 :doc "Utils for data insert tasks."}
004 (:require [clojure.string :as string]))
005
006 (defn check-kw [m kw] (when (contains? m kw) kw))
007
008 (defn ensure-map
009 "Ensures `x`to be a map. If `x` is a value a map is constucted from
010 the last keyword and the value.
011
012 Example:
013 ```clojure
014 (ensure-map 10 [:a :b :c])
015 ;; =>
016 ;; [{:c 10} [:a :b]]
017 (ensure-map {:d 10} [:a :b :c])
018 ;; =>
019 ;; [{:d 10} [:a :b :c]]
020 ```"
021 [x v]
022 (if (map? x)
023 [x v]
024 [{(last v) x} (into [] (butlast v))]))
025
026 (defn ensure-vec
027 "Ensures that `v` is a vector even if `v` is `nil`.
028
029 Example:
030 ```clojure
031 ;; important:
032 (ensure-vec nil)
033 ;;=> [nil]
034 ;; ^^ because:
035 (concat [1 2] nil)
036 ;; => (1 2) ; but we need:
037 (concat [1 2] [nil])
038 ;; => (1 2 nil)
039 ;; to ensure that all
040 ;; Value-vectors keep the same length
041 (ensure-vec 1)
042 ;; [1]
043 (ensure-vec [1])
044 ;; [1]
045 ```"
046 [v]
047 (if (vector? v) v [v]))
048
049 (defn vector-if
050 "Makes the value `v` of keyword `kw` a vector also if `v` is `nil`."
051 [m kw]
052 (if (and (map? m) (keyword? kw))
053 (if-let [v (kw m)] (assoc m kw (ensure-vec v)) m)))
054
055 (defn replace-if
056 "Replaces `v`alue of `k`ey in struct if `v`is not `nil`.
057
058 Example:
059 ```clojure
060 (replace-if {:Type \"a\"} :Type \"b\")
061 ;; {:Type \"b\"}
062 ```
063 "
064 [m k v]
065 (if (keyword? k) (assoc m k v) m))
066
067 (defn append-if
068 "Appends `v` to the value of `k`. If `k` does not exist in `m`,
069 `k [v]` is assoced. If `k` does exist in `m`, `v` is conjed.
070
071 Example:
072 ```clojure
073 (append-if {:Value [1 2 3]} :Value 4)
074 ;; {:Value [1 2 3 4]}
075 ```"
076 [m k v]
077 (if (keyword? k)
078 (let [new-v (ensure-vec v)]
079 (if-let [old-v (k m)]
080 (assoc m k (into [] (concat old-v new-v)))
081 (assoc m k new-v)))
082 m))
083
084 (defn path->kw-vec
085 "Turns the path into a vector of keywords.
086
087 Example:
088 ```clojure
089 (path->kw-vec \"a.b.c\")
090 ;; [:a :b :c]
091 ```"
092 [s]
093 {:pre [(string? s)]}
094 (mapv keyword (string/split s (re-pattern "\\."))))