clojure-spec

ghaskins 2025-04-09T16:49:20.460419Z

Is there a way to pass context to rules when running s/valid?

ghaskins 2025-04-09T16:50:45.069009Z

I often times find myself needing extra info, such as checking the referential integrity of a key to some other part of the map, or perhaps even a call to something outside of the data-structure, but I have no way that I know of to do this with spec so I end up doing it another way

ghaskins 2025-04-09T16:52:29.876129Z

As a trivial example, say I have a structure like {:foo {“bar” 42 “baz” 43} :bat “bar”}

ghaskins 2025-04-09T16:53:43.466569Z

and I want some rule structure like

(s/def ::bat bat-valid?)
(s/def ::x (s/keys :req-un [::bat]))

ghaskins 2025-04-09T16:54:52.296919Z

but bat-valid? can only appropriately be written if it can check that [:foo “bar”] exists, can I somehow pass a context such that (in this case), I can check other parts of the tree via bat )

2025-04-09T16:55:26.890439Z

In the most general sense that means you should be using s/and with a predicate that checks the whole map

ghaskins 2025-04-09T16:55:44.545229Z

yeah, i was just thinking about that as I was asking my question

ghaskins 2025-04-09T16:56:00.667739Z

ty…ill give that a go

2025-04-09T16:56:05.116889Z

If you need more information to validate, then your spec should be applied at the level where the information is

ghaskins 2025-04-09T16:56:13.727879Z

That makes sense

2025-04-09T16:57:17.197359Z

There are maybe hacks you could do using binding, but they won't be very clean

ghaskins 2025-04-09T16:57:37.177139Z

Got it. I wasnt sure if there was something built-in to spec that I didnt know about

ghaskins 2025-04-09T16:57:49.765869Z

but the top-level validator makes sense, so ill try that approach