Commits

Meikel Brandmeyer committed 982b11f

Add transform main entry point

Comments (0)

Files changed (1)

src/main/clojure/aspect/core.clj

 ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 ; THE SOFTWARE.
 
-(ns aspect.core)
+(ns aspect.core
+  (:import
+    clojure.lang.IPersistentMap
+    clojure.lang.IPersistentVector
+    clojure.lang.ISeq))
+
+(defmulti transform
+  "Transform a value according to a given converter. Converters are
+  plain old functions. And the default is to just call the converter
+  with the value.
+  
+  If the converter is a map, it is considered as a map from keys to
+  converters, which are applied to the corresponding key in the value.
+  Keys without a corresponding equivalent in the converter map are
+  left untouched.
+  
+  If the converter is a seq, it is considered as a sequence of
+  converters, which is applied to the corresponding element of the
+  value. If the value is a vector the result is again a vector."
+  {:arglists '([value converter])}
+  (fn transform-dispatch [value converter] [(type value) (type converter)]))
+
+(defmethod transform :default
+  [value converter]
+  (converter value))
+
+(defmethod transform [IPersistentVector Object]
+  [value converter]
+  (vec (transform (seq value) converter)))
+
+(defmethod transform [ISeq Object]
+  [value converter]
+  (map transform value converter))
+
+(defmethod transform [Object IPersistentMap]
+  [value converter]
+  (->> (keys converter)
+    (map #(vector % (transform (get value %) (get converter %))))
+    (into value)))