is there a way to make a spec validate a reference to another key's value? let's say you have a (s/coll double?)
and you want to make a key where the predicate is something like (s/and double? #(= % (apply + ,,,))
where the ,,,
is that (s/coll double?)
maybe your schema is like (s/schema [::double-list ::sum])
I'm prolly not doing a great job of explaining this, does it vaguely make sense?
Can you give an example of valid data?
The example you gave should basically work so I’m trying to make sure I understand what you mean
Are you talking about in a map?
ya
You can s/and a predicate that validates whatever you want
ok, so let's say concretely, I've got something like: {::prices '(1 2 3 4) ::total 10}
and so total
's predicate has to match the collection of prices (except doubles instead of ints)
so, how would a (s/def ::total)
's predicates (apply +
on ::prices
?
(s/def ::m (s/and (s/keys ...) (fn [{::keys [total prices]}] (= total (reduce + prices))))
Just spec ::total as an int? or whatever
oh!
ok great!
The attribute by itself does not have this constraint
It only has that constraint when combined with prices in a map
I'm not sure I grok that yet
The total=prices is a property of the map, not of the total
ah, right
(s/def ::total int?)
(s/def ::prices (s/coll-of int?))
(s/def ::m (s/and (s/keys :req [::total ::prices])
(fn [{::keys [total prices]}] (= total (reduce + prices)))))
(s/valid? ::m {::prices '(1 2 3 4) ::total 10})
this spits out an java.lang.IndexOutOfBoundsException
(let [{::keys [total prices]} {::prices '(1 2 3 4) ::total 10}]
(= total (reduce + prices))) ;=> true
((fn [{::keys [total prices]}]
(= total (reduce + prices))) {::prices '(1 2 3 4) ::total 10}) ;=> true
(s/def ::m (fn [{::keys [total prices]}]
(= total (reduce + prices)))) ;=> java.lang.IndexOutOfBoundsException
(s/def ::m (s/and (s/keys :req [::total ::prices])
(fn [{::keys [total prices]}]
(= total (reduce + prices))))) ;=> :scratch/m
(s/valid? ::m {::prices '(1 2 3 4) ::total 10}) ;=> java.lang.IndexOutOfBoundsException