Fork me on GitHub

I'm not even sure exactly what this would mean, but is it possible to 'render' a spec for display in for example a Swagger UI? I'm wanting to build a web UI for displaying the specs of commands that could be sent to the system, but I'm not sure if this is even possible, as Spec is so flexible


@danielcompton we have been working on the api-docs thing, just finished on the spec -> json schema and will do the -> openapi next. also have some tooling for the runtime conforming needed to support different wire-formats. But like Schema (and ring-swagger), spec is more powerful than the openapi spec, so some information will be lost. Might be a place to do full-clojure thing, with own “spec-ui”.


any schedule for cljs-port of the spec-alpha?


@ikitommi yeah, I don't specifically want Swagger, it was just the closest thing I could think of, a spec-ui would be what I was after


I think the spec-ui could be done easily, as the spec forms can be serialized. Also, something like the but for spec. Both on todo-list, but with million other things.


@alexmiller I would like to add the var to the ex-data in clojure.core/macroexpand-check. so v in


so either the v itself or the (->sym v) that is currently used in the message for the ex-data call


I'm experimenting with some different error presentations and currently the var isn't accessible so can't show the root spec that failed (other than "parsing" the (.getMessage ex))


could either do this in the macroexpand-check or in the catch that wraps the error in


Hi -- How do you make a spec for a particular value? (partial = :value) predicate doesn't seem very idiomatic.


Unless your value is nil or false 🙂


But then you have specific preds


Thanks! This should work fine and looks more idiomatic than partial.


Hi clojurians! How does one make up a spec for a huge nested map that may have different values for the same key but in different places? like this:

{:a [{:foo "foo1" :bar 1}, {:foo "foo2" :bar 8}]
 :b {:baz  {:foo 3 :bar "quuz"}
     :quux {:foo [1 2 3] :baz 10}}
How do I say that :foo is usually a string, but inside a certain context (b/baz in this case) it's a number, and in certain others (b/quux) it's a vector?


@vandr0iy If you're asking how you can make s/keys behave like that, the short answer is: it's not what it was designed for but rather it relies on namespaced keywords. However, you could define keywords of the same name in different namespaces representing your various contexts and piece the specs together accordingly with :req-un and :opt-un.


@vandr0iy errr....ok, they might help, but don't think they solve your different values for the same key problem, @dergutemoritz answer seems to be it


@vandr0iy @U4VDXB2TU: data-spec can do that, but I would use the normal s/keys if you need to reuse the attribute specs elsewhere. If it’s just a ~one-time thing, then something like this:

(require '[clojure.spec :as s])
(require '[spec-tools.core :as st])

(def spec
    {:a [{:foo string? :bar int?}]
     :b {:baz {:foo int? :bar string?}
         :quux {:foo [int?] :baz int?}}}))

(def data
  {:a [{:foo "foo1" :bar 1}, {:foo "foo2" :bar 8}]
   :b {:baz  {:foo 3 :bar "quuz"}
       :quux {:foo [1 2 3] :baz 10}}})

(s/valid? spec data)
; true


in the end I just ended up doing specs for every single element that might be recognized as a pattern in its own namespace with the same name as it's called in the data structure I want to specify - but in its own namespace. For instance:

(s/def :type1/stuff string?)
(s/def :type1/foo (s/keys :req-un [:type1/stuff]))

(s/def :type2/stuff number?)
(s/def :type2/element (s/keys :req-un [:type2/stuff]))
(s/def :type2/foo (s/coll-of :type2/element))
this way stuff is a string in a type1 element and a number in type2 one. This data would match:
(s/valid? :type1/foo {:stuff "foo"})
=> true
(s/valid? :type1/foo {:stuff 2})
=> false
(s/valid? :type2/foo [{:stuff 2} {:stuff 4}])
=> true
(s/valid? :type2/foo [{:stuff 2} {:stuff "arst"}])
=> false

Alex Miller (Clojure team)11:04:22

@ikitommi re cljs, will happen soon, after clj is done


@alexmiller not sure, will try it. thx


thanks @alexmiller, looking forward to it.


@alexmiller yep should do, I can get the name of the spec via the meta :clojure.spec/name


which corresponds to the var

Alex Miller (Clojure team)12:04:04

I guess I'm not sure why you want the var vs the name


for now just the name, maybe the var later. thinking that the var might contain more metadata, will see if I need that


probably not though