diff --git a/src/clj_pebble/convert.clj b/src/clj_pebble/convert.clj new file mode 100644 index 0000000..ec479f8 --- /dev/null +++ b/src/clj_pebble/convert.clj @@ -0,0 +1,71 @@ +(ns clj-pebble.convert + (:require [clj-pebble.options :refer [options]])) + +(defprotocol JavaToClojure + (to-clojure [x])) + +(extend-protocol JavaToClojure + java.util.Collection + (to-clojure [x] + (->> x + (map to-clojure) + (doall))) + + java.util.Map + (to-clojure [x] + (->> x + (.entrySet) + (reduce + (fn [m [k v]] + (assoc m + (if (and (:auto-convert-map-keywords @options) + (string? k)) + (keyword k) + (to-clojure k)) + (to-clojure v))) + {}))) + + java.lang.Object + (to-clojure [x] + x) + + nil + (to-clojure [_] + nil)) + +(defprotocol ClojureToJava + (to-java [x])) + +(extend-protocol ClojureToJava + clojure.lang.IPersistentMap + (to-java [x] + (let [hashmap (new java.util.HashMap (count x))] + (doseq [[k v] x] + (.put hashmap + (if (and (:auto-convert-map-keywords @options) + (keyword? k)) + (name k) + (to-java k)) + (to-java v))) + hashmap)) + + clojure.lang.IPersistentCollection + (to-java [x] + (let [array (new java.util.ArrayList (count x))] + (doseq [item x] + (.add array (to-java item))) + array)) + + java.lang.Object + (to-java [x] + x) + + nil + (to-java [_] + nil)) + +(defn java->clojure [x] + (to-clojure x)) + +(defn clojure->java [x] + (to-java x)) \ No newline at end of file diff --git a/src/clj_pebble/extensions.clj b/src/clj_pebble/extensions.clj index 38dddc7..979a80b 100644 --- a/src/clj_pebble/extensions.clj +++ b/src/clj_pebble/extensions.clj @@ -1,7 +1,8 @@ (ns clj-pebble.extensions (:import (java.util Map) (com.mitchellbosecke.pebble PebbleEngine) - (com.mitchellbosecke.pebble.extension Function Filter Test))) + (com.mitchellbosecke.pebble.extension Function Filter Test)) + (:require [clj-pebble.convert :refer [java->clojure clojure->java]])) (defn- get-sorted-args [args-map] (->> args-map @@ -11,23 +12,26 @@ (sort-by first) (map second))) +(defn- convert-args [args-map] + (map java->clojure (get-sorted-args args-map))) + (defn make-function [f] (reify Function (getArgumentNames [_] nil) (execute [_ args] - (apply f (get-sorted-args args))))) + (clojure->java (apply f (convert-args args)))))) (defn make-filter [f] (reify Filter (getArgumentNames [_] nil) (apply [_ input args] - (apply f (concat [input] (get-sorted-args args)))))) + (clojure->java (apply f (concat [input] (convert-args args))))))) (defn make-test [f] (reify Test (getArgumentNames [_] nil) (apply [_ input args] - (boolean (apply f (concat [input] (get-sorted-args args))))))) + (boolean (apply f (concat [input] (convert-args args))))))) (defn add-function! [^PebbleEngine engine ^String name f] (.put (.getFunctions engine) name (make-function f)))