Fork me on GitHub

I'm trying to make a GET route with a query parameter that can be either a Long or a Date. I have

(GET* "/history" []
                :summary "Get the transaction history diffs of the database"
                :query-params [{begin :- TimePoint nil} {end :- TimePoint nil} {limit :- Long 50} {offset :- Long 0}]
                :return s/Any
(s/defschema TimePoint
  (s/maybe (s/either java.util.Date Long)))
However, when I do curl -s -G -d begin=1598495 -d limit=2 http://…, my number is not converted from String to Long, and I get this:
{"errors":{"begin":"(not (some-matching-either-clause? \"1598495\"))"}}
Is there a way to get it to convert (as it does if I specify just Long instead of TimePoint—but then I lose the ability to pass either a number or a date)?


Query parameters will be strings so they would have to be coerced to Long or Date. Either Schema doesn't support coercion.


@juhoteperi ideas how that could be implemented? With cond-pre maybe?


or a custom coercer?


If a TimePoint would just be a Date and one would add a Long->Date matcher to string-coercer.. might work. Not near a computer, can't test thou.


I don't know how conditional works with coercion and I don't know what kind of predicate it would need


the Long in this case is a Datomic database t, so it needs to stay a Long.


I'm trying stuff like this, but haven't gotten it to quite work in context yet:

(s/defschema TimePoint
  (s/maybe (s/either java.util.Date Long)))

(defn timepoint-matcher [schema]
  (when (= schema TimePoint)
    (fn [x]
      (if (= x "")
        (or (try
              (Long/parseLong x)
              (catch NumberFormatException e nil))
            (clojure.instant/read-instant-date x))))))

(def timepoint-coercer (coerce/coercer TimePoint timepoint-matcher))