Clojure Dependent Fields Spec

I have an entry for this specification, too, and I want to generate values, but make sure that the current amount does not exceed the maximum amount. A simplified specification would look something like this:

(s/def ::max-amt (s/and number? #(<= 0 % 1e30))) (s/def ::cur-amt (s/and number? #(<= 0 % 1e30))) (s/def ::loan (s/cat :max-amt ::max-amt :cur-amt ::cur-amt)) 

I know that I can have s/and in the ::loan specification, but I need something like:

 (s/def :loan (s/cat :max-amt ::max-amt ;; not a real line: :cur-amt (s/and ::cur-amt #(< (:cur-amt %) (:max-amt %))))) 

Is this type of restriction available in the specification?

Note: I know that I can replace cur-amt with a number from 0 to 1, which represents the fractional part, but then I change the data to fit the code, and not vice versa, I do not control the data source in the real application here.

+5
source share
1 answer

This should work (adapted from this discussion ):

 (s/def ::loan (s/and (s/keys :req [::cur-amt ::max-amt]) (fn [{:keys [::cur-amt ::max-amt]}] (< cur-amt max-amt)))) (s/conform ::loan {:cur-amt 50 :max-amt 100}) ; => {:cur-amt 50 :max-amt 100} (s/conform ::loan {:cur-amt 100 :max-amt 50}) ; => :clojure.spec/invalid 

Or if you want to stick with s/cat :

 (s/def ::loan (s/and (s/cat :cur-amt ::cur-amt :max-amt ::max-amt) (fn [{:keys [cur-amt max-amt]}] (< cur-amt max-amt)))) (s/conform ::loan [50 100]) ; => [50 100] (s/conform ::loan [100 50]) ; => :clojure.spec/invalid 
+3
source

Source: https://habr.com/ru/post/1260892/


All Articles