I'm working through Modern ClojureScript tutorial, and trying to write some macros to automate some things.
For instance, in one of validate functions:
(defn validate-shopping-form [quantity price tax discount]
(validate {:quantity quantity :price price :tax tax :discount discount}
;; validate presence
[:quantity present? "Quantity can't be empty"]
[:price present? "Price can't be empty"]
[:tax present? "Tax can't be empty"]
[:discount present? "Discount can't be empty"]
;; validate type
[:quantity integer-string? "Quantity has to be an integer number"]
[:price decimal-string? "Price has to be a number"]
[:tax decimal-string? "Tax has to be a number"]
[:discount decimal-string? "Discount has to be a number"]
;; validate range
[:quantity (gt 0) "Quantity can't be negative"]
;; other specific platform validations (not at the moment)
))
I've wrote some macros, but my function does not compile. And i don't understand why
(ns try-cljs.shopping.validators
(:require [valip.core :refer [validate]]
[valip.predicates :refer [present?
integer-string?
decimal-string?
gt]]))
(defmacro empty-checks []
`(list ~@(map (fn [x] [(keyword x) 'present? (str x " can't be empty")])
["quantity" "price" "tax" "discount"])))
(defmacro number-checks []
`(list ~@(mapv (fn [x] [(keyword x) 'decimal-string? (str x " should be a number")])
["price" "tax" "discount"])))
(defmacro quantity-checks []
`(list [:quantity integer-string? "quantity should be an integer"]
[:quantity (gt 0) "quantity should be positive"]))
(defmacro checks [] `(list ~@(empty-checks)
~@(number-checks)
~@(quantity-checks)))
(defn validate-shopping-form [quantity price tax discount]
(apply validate {:quantity quantity :price price :tax tax :discount discount}
(checks)))
The error is: java.lang.IllegalArgumentException: No matching ctor found for class valip.predicates$gt$fn__2332
And it is about (gt 0)
form. But what does this mean and how can i fix the macros?
By the way. In the REPL expression
(apply validate {:quantity "10"} (concat (quantity-checks)))
works fine