clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
NoahTheDuke 2021-05-04T15:41:17.116300Z

i'm looking to write a spec that checks a list of tuples to see if there's 0 or 1 tuple that starts with some value

NoahTheDuke 2021-05-04T15:42:12.117100Z

i have the spec that verifies and conforms that the shape is correct:

(s/def ::handler-clause (s/cat :name (s/nonconforming
                                       (s/or :keyword keyword?
                                             :class symbol?))
                               :arglist vector?
                               :body (s/* any?)))

NoahTheDuke 2021-05-04T15:42:42.117600Z

and then in the fdef i have (s/* (s/spec ::handler-clause)) for that argument

NoahTheDuke 2021-05-04T15:44:20.119200Z

inputs look like [:error [& args] (println args)] or [:no-error [& args] args]

borkdude 2021-05-04T15:44:30.119500Z

* means 0 or more, not 0 or 1

alexmiller 2021-05-04T15:44:41.119800Z

? is for 0 or 1

NoahTheDuke 2021-05-04T15:45:13.120500Z

my apologies, i mean, i'd like to have it check that there is any number of tuples that don't start with :no-error and 0 or 1 tuples that start with :no-error

NoahTheDuke 2021-05-04T15:49:11.122100Z

so something like

(s/fdef handler-case
  :args (s/cat :expr any?
               :bindings (s/and (s/? (s/cat :name (s/and #(= :no-error %)
                                                         (s/nonconforming
                                                           (s/or :keyword keyword?
                                                                 :class symbol?)))
                                            :arglist vector?
                                            :body (s/* any?)))
                                (s/* (s/cat :name (s/and #(not= :no-error %)
                                                         (s/nonconforming
                                                           (s/or :keyword keyword?
                                                                 :class symbol?)))
                                            :arglist vector?
                                            :body (s/* any?)))
                           )))