Implement recursive function value expansion (for maps)
This commit is contained in:
parent
c9d4c1316b
commit
b9016aff99
2 changed files with 95 additions and 0 deletions
59
src/monger/internal/fn.clj
Normal file
59
src/monger/internal/fn.clj
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
;; Copyright (c) 2011-2012 Michael S. Klishin
|
||||||
|
;;
|
||||||
|
;; The use and distribution terms for this software are covered by the
|
||||||
|
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
||||||
|
;; which can be found in the file epl-v10.html at the root of this distribution.
|
||||||
|
;; By using this software in any fashion, you are agreeing to be bound by
|
||||||
|
;; the terms of this license.
|
||||||
|
;; You must not remove this notice, or any other, from this software.
|
||||||
|
|
||||||
|
(ns monger.internal.fn)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Implementation
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defn- apply-to-values [m f]
|
||||||
|
"Applies function f to all values in map m"
|
||||||
|
(into {} (for [[k v] m]
|
||||||
|
[k (f v)])))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; API
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defprotocol IFNExpansion
|
||||||
|
(expand-all [x] "Invokes functions, recursively expands maps, evaluates all other values to themselves"))
|
||||||
|
|
||||||
|
(extend-protocol IFNExpansion
|
||||||
|
java.lang.Integer
|
||||||
|
(expand-all [i] i)
|
||||||
|
|
||||||
|
java.lang.Long
|
||||||
|
(expand-all [l] l)
|
||||||
|
|
||||||
|
java.lang.String
|
||||||
|
(expand-all [s] s)
|
||||||
|
|
||||||
|
java.lang.Float
|
||||||
|
(expand-all [f] f)
|
||||||
|
|
||||||
|
java.lang.Double
|
||||||
|
(expand-all [d] d)
|
||||||
|
|
||||||
|
java.util.Map
|
||||||
|
(expand-all [m] (apply-to-values m expand-all))
|
||||||
|
|
||||||
|
clojure.lang.PersistentVector
|
||||||
|
(expand-all [v] v)
|
||||||
|
|
||||||
|
clojure.lang.APersistentMap
|
||||||
|
(expand-all [m] (apply-to-values m expand-all))
|
||||||
|
|
||||||
|
clojure.lang.IFn
|
||||||
|
(expand-all [f] (f))
|
||||||
|
|
||||||
|
Object
|
||||||
|
(expand-all [x] x))
|
||||||
36
test/monger/test/internal/fn.clj
Normal file
36
test/monger/test/internal/fn.clj
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
(ns monger.test.internal.fn
|
||||||
|
(:use [clojure.test]
|
||||||
|
[monger.internal.fn]))
|
||||||
|
|
||||||
|
|
||||||
|
(deftest test-recursive-function-values-expansion
|
||||||
|
(are [i o] (is (= (expand-all i) o))
|
||||||
|
{ :int (fn [] 1) :str "Clojure" :float (Float/valueOf 11.0) } { :int 1 :str "Clojure" :float (Float/valueOf 11.0 )}
|
||||||
|
{ :long (fn [] (Long/valueOf 11)) } { :long (Long/valueOf 11) }
|
||||||
|
{
|
||||||
|
:i 1
|
||||||
|
:l (Long/valueOf 1111)
|
||||||
|
:s "Clojure"
|
||||||
|
:d (Double/valueOf 11.1)
|
||||||
|
:f (Float/valueOf 2.5)
|
||||||
|
:v [1 2 3]
|
||||||
|
:dyn-i (fn [] 1)
|
||||||
|
:dyn-s (fn [] "Clojure (expanded)")
|
||||||
|
:m { :nested "String" }
|
||||||
|
:dyn-m { :abc (fn [] :abc) :nested { :a { :b { :c (fn [] "d") } } } }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
:i 1
|
||||||
|
:l (Long/valueOf 1111)
|
||||||
|
:s "Clojure"
|
||||||
|
:d (Double/valueOf 11.1)
|
||||||
|
:f (Float/valueOf 2.5)
|
||||||
|
:v [1 2 3]
|
||||||
|
:dyn-i 1
|
||||||
|
:dyn-s "Clojure (expanded)"
|
||||||
|
:m { :nested "String" }
|
||||||
|
:dyn-m {
|
||||||
|
:abc :abc
|
||||||
|
:nested { :a { :b { :c "d" } } }
|
||||||
|
}
|
||||||
|
}))
|
||||||
Loading…
Reference in a new issue