1
votes

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
Do you have a specific example? Generally speaking, your inner/nested specs are not going to receive ancestral data, but it's possible you could solve the problem with the outer spec.Taylor Wood
I am wanting to validate some yaml that represents a complex datastructure. The validation point I want to prove is where one part of the structure references another part of the same structure, but I want to prove that the referenced part actually exists. This means being about to apply a predicate at the point of reference and back track up the yaml tree and then back down to the point of the referenced item. To do this I need to be able to get the parent of the spec that is validating the reference.mmer
It looks like you want us to write some code for you. While many users are willing to produce code for a coder in distress, they usually only help when the poster has already tried to solve the problem on their own. A good way to demonstrate this effort is to include the code you've written so far, example input (if there is any), the expected output, and the output you actually get (console output, tracebacks, etc.). The more detail you provide, the more answers you are likely to receive. Check the FAQ and How to Ask.marco.m

1 Answers

0
votes

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.