juxt / aero

A small library for explicit, intentful configuration.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there any way to retain the information in a ref's path?

WhittlesJr opened this issue · comments

My use case has me trying to get at the path of my #ref without re-writing it somewhere else in the given context. For example:

;; Config
{:primitive-thing {:some   :shared
                   :values true}

 :other-thing #build-thing {:referenced-thing #ref [:primitive-thing]}}

;; An ideal reader
(defmethod aero/reader 'build-thing [_ _ thing]
  (->> thing
       :referenced-thing
       (meta)
       :ref-path
       (assoc thing :knows-about)))

;; End result
{:primitive-thing {:some   :shared
                   :values true}
 :other-thing     {:referenced-thing {:some   :shared
                                      :values true}
                   :knows-about      [:primitive-thing]}}

Is this possible today, perhaps through a different approach? If not, is this easy enough to add?

This is a pretty funky use case. I don't think there's a way to annotate the value reliably, as there's many data types (numbers) which don't take metadata. There's also cases like #ref #ref [:path-to-ks] to think about. One suggestion is to look at the macro system in aero, and see if that satisfies your needs. At the least, it would let you build a custom #ref (e.g. #refwithmeta) and use that instead.

I tried to make my own reader, but couldn't figure out how to actually make it work.

If the data type is not a clojure.lang.IObj or whatever, you can just not use with-meta. I actually found a spot in the code that I could reasonably inject just such a conditional with-meta, but the metadata gets lost on its way through Aero's expansion logic, and that logic is a real bear to try to grok.

But anyway, I decided to go with Integrant instead of Aero. My config is not a stateful system, but Integrant handles my use case beautifully, without needing to shovel metadata around.