add value conversion for func/filter/test args & func/filter return vals

the main purpose of this is for the :auto-convert-map-keywords option,
but this also converts collection types to/from types that Pebble uses
natively... to be honest though, there's *probably* not much value in
that and we could likely just use something like prewalk to just
convert map keywords ... ? might be faster too?
This commit is contained in:
Gered 2014-11-15 12:22:53 -05:00
parent e1812476f0
commit 72f44a278c
2 changed files with 79 additions and 4 deletions

View file

@ -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))

View file

@ -1,7 +1,8 @@
(ns clj-pebble.extensions (ns clj-pebble.extensions
(:import (java.util Map) (:import (java.util Map)
(com.mitchellbosecke.pebble PebbleEngine) (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] (defn- get-sorted-args [args-map]
(->> args-map (->> args-map
@ -11,23 +12,26 @@
(sort-by first) (sort-by first)
(map second))) (map second)))
(defn- convert-args [args-map]
(map java->clojure (get-sorted-args args-map)))
(defn make-function [f] (defn make-function [f]
(reify Function (reify Function
(getArgumentNames [_] nil) (getArgumentNames [_] nil)
(execute [_ args] (execute [_ args]
(apply f (get-sorted-args args))))) (clojure->java (apply f (convert-args args))))))
(defn make-filter [f] (defn make-filter [f]
(reify Filter (reify Filter
(getArgumentNames [_] nil) (getArgumentNames [_] nil)
(apply [_ input args] (apply [_ input args]
(apply f (concat [input] (get-sorted-args args)))))) (clojure->java (apply f (concat [input] (convert-args args)))))))
(defn make-test [f] (defn make-test [f]
(reify Test (reify Test
(getArgumentNames [_] nil) (getArgumentNames [_] nil)
(apply [_ input args] (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] (defn add-function! [^PebbleEngine engine ^String name f]
(.put (.getFunctions engine) name (make-function f))) (.put (.getFunctions engine) name (make-function f)))