Clojure Spec accessing data in hierarchical spec

If you have a set of specs that are used to validate a hierarchical set of data - say a yaml file. From one of the child specs, is it possible to reference data that occurs earlier in the tree?

1 answer

  • answered 2017-10-11 10:22 Taylor Wood

    This is an example of one approach you could take:

    (s/def ::tag string?)
    
    (s/def ::inner (s/keys :req-un [::tag]))
    
    (s/def ::outer
      (s/and
        (s/keys :req-un [::inner ::tag])
        #(= (:tag %) ;; this tag must equal inner tag
            (:tag (:inner %)))))
    
    (s/conform ::outer {:tag "y" ;; inner doesn't match outer
                        :inner {:tag "x"}})
    ;=> :clojure.spec.alpha/invalid
    
    (s/conform ::outer {:tag "x"
                        :inner {:tag "x"}})
    ;=> {:tag "x", :inner {:tag "x"}}
    

    Depending on your requirements you might be able to make your assertions like this, from the outside-in rather than inside-out.