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 "\\."))))