-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
s/or causes inconsistent results with st/coerce #212
Comments
Note that if (s/def ::s (s/keys :req-un [::keyword ::date])) then the coercion works as expected: (st/coerce ::s {:keyword "a" :date dt} st/json-transformer)
=> {:keyword :a, :date #inst"2020-02-22T00:00:00.000-00:00"} |
Also, if the two (s/def ::s (s/or :y (s/keys :req-un [::keyword ::date])
:x (s/keys :req-un [::keyword ::int]))) then the coercion also works as expected: (st/coerce ::s {:keyword "a" :date dt} st/json-transformer)
=> {:keyword :a, :date #inst"2020-02-22T00:00:00.000-00:00"} |
Note that a workaround (of sorts) for this problem is simply to apply the coercion twice; i.e. (st/coerce ::s
(st/coerce ::s {:keyword "a" :date dt} st/json-transformer)
st/json-transformer)
=> {:keyword :a, :date #inst"2020-02-22T00:00:00.000-00:00"} This works because the result of the first coercion causes the value for |
Thanks for a fine project! |
I am also wondering when is the next release that will include this patch. Otherwise, I'd like to thank the developers of this project as well. The coercion and data-specs features makes using spec a much more intuitive experience! |
Hello, I think have encountered a variation of this issue through Reitit. Using (require '[clojure.spec.alpha :as s]
'[spec-tools.core :as st])
(s/def ::keyword keyword?)
(s/def ::int int?)
(s/def ::date inst?)
(s/def ::s (s/merge
(s/keys :req-un [::keyword])
(s/or :x (s/keys :req-un [::int])
:y (s/keys :req-un [::date]))))
(st/coerce ::s {:keyword "a" :date "2020-02-02"} st/strip-extra-keys-transformer)
=> {}
(st/coerce ::s
{:keyword "a" :int "1"}
(st/type-transformer
st/strip-extra-keys-transformer
st/json-transformer))
=> {} I encountered this because the default coercion settings in (def json-transformer
(st/type-transformer
st/strip-extra-keys-transformer
st/json-transformer)) I am using:
|
I've taken a look at the issue of reitit's The issue spawns from the Following @ikitommi 's comment at issue 178, I have implemented a toy solution: (defmethod walk :or [{:keys [::parse/items]} value accept options]
(defn walk-or-helper
"for a particular `item` of the spec, this function coerces that `value`
into that `item` and returns the coerced value if `valid?`"
[item]
(let [transformed (accept item value options)
valid? (some-> item :spec (s/valid? transformed))]
{:transformed transformed :valid? valid?}))
;; iterate above function, return valid value or the last one or original value
(let [valid-items (for [item items]
(walk-or-helper item))]
(or (-> (filter #(:valid? % ) valid-items) (last) :transformed)
(:transformed (last valid-items))
value))) Issues with the proposed solutionNow, I think that needs some more thought, and it also fails some tests. Testing Composed Smaller changes |
I've just had an opportunity to revisit this issue and it looks like it has been fixed - I can't replicate with version So, closing. |
there's still some remaining weirdness, see #255 |
Consider that I define the following contrived specs:
Now we can try some coercions:
So far so good: the values in the maps are coerced to "json friendly" form; but...
i.e. why is the
:date
value now not coerced to aninst
?The text was updated successfully, but these errors were encountered: