;; Copyright (C) 2023 Felisp ;; ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU Affero General Public License as published by ;; the Free Software Foundation, version 3 of the License. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU Affero General Public License for more details. ;; ;; You should have received a copy of the GNU Affero General Public License ;; along with this program. If not, see . (ns rss-thread-watch.utils "Util functions" (:gen-class)) ;; ===== Macros ===== (defmacro nil?-else "Return x unless it's nil, the return y" [x y] `(let [result# ~x] (if (nil? result#) ~y result#))) (defmacro when-else "Evaluates [tst], if it's truthy value returns that value. If it's not, execute everything in [else] and return last expr." [tst & else] `(let [res# ~tst] (if res# res# (do ~@else)))) (defmacro ret= "compares two values using [=]. If the result is true returns the value, else the result of [=]. Usefull with if-else" [x y] `(let [x# ~x y# ~y result# ~(= x y)] (if result# ~x result#))) ;; ===== Generic functions ==== (defn indices ;; https://stackoverflow.com/questions/8641305/find-index-of-an-element-matching-a-predicate-in-clojure "Returns indexes of elements passing predicate" [pred coll] (keep-indexed #(when (pred %2) %1) coll)) (defn map-apply-defaults "Apply default values from [defaults] to keys not present in [conf] Order is very important. Thus all missing values from config are replaced by defaults" [conf defaults] (into conf (for [k (keys defaults)] (let [conf-val (get conf k) default-val (get defaults k)] (if (and (map? conf-val) ; both are maps, we have to go level deeper (map? default-val)) ; If only one is, we don't care cus then it's just assigment {k (map-apply-defaults conf-val default-val)} {k (nil?-else conf-val default-val)}))))) (defn fmap [f m] "Applies function [f] to every key and value in map [m] Function signature should be (f [key value])." (into (empty m) (for [[key val] m] [key (f key val)])))