So in relation to the problem I described a few days ago, I wrote a function which attempts to determine whether some zloc is in the key position of a map. But I think it only works for the first map entry
(defn map-key?
[zloc]
(and
(zip/map? (zip/up zloc))
(zip/leftmost? zloc)))
Anyone know how this could be written to match a key in any map entry?Or maybe it’s better to just identify the containing maps and replace them as a whole?
@cddr how I approached this in rewrite-edn: I just treated every nth element as a key and every n+1th element as a value
@cddr if you need to, you might also want to consider accounting for any #_ that might be present. Example {:a #_ ignored-thing 1}
Oh fortunately I don’t think I’ll need to worry about that but thanks for the headsup
was wondering if anybody could help here, when I do this
(z/sexpr (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}"))
I end up with
#:db.sql{:connection (read-string "#profile\n{:prod {:jdbc-url #env JDBC_URL}}")}
is there a way to roundtrip this properly?@yogthos you can do this by (binding [*print-namespace-maps* false] ...) , forgive me the bolded font, it's supposed to be earmuffed.
ah perfect!
hmm, I can't find where *print-namespace-maps* is defined though
in clojure.core :)
ohh
the printing behavior you saw comes from clojure, not from rewrite-clj
haha I thought it was a rewrite-clj thing
these are corners of Clojure I haven't explored yet 🙂
hmm no dice
(binding [*print-namespace-maps* false]
(z/sexpr (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}")))
it's this bit that's causing trouble (read-string "#profile\n{:prod {:jdbc-url #env JDBC_URL}}")
oh what does it say?
I see
yeah not sure why it ends up getting wrapped with read-string
I think this is because you cannot convert #profile ..." to an s-expression without letting rewrite-clj know how to resolve that reader tag
why do you need the s-expressions, perhaps there is a better alternative?
I just need to inject a piece of edn into a file, so yeah maybe I'm barking up a wrong tree here
I use a zipper to find the target location, and then do this
(defn edn-merge-value [value]
(fn [node]
(if-let [inside-map (z/down node)]
(-> inside-map
(z/rightmost)
(zipper-insert-kw-pairs (z/down value)))
(z/replace node (z/node (format-zloc value))))))
I don't see sexpr in there?
you can use str instead to get back the string instead
sexpr should really be used with caution
oh I see
but using str on a node will give a map containing the zipper
you first need to do (z/node ...)
and also z/root ... if you're not at the root of the zipper
ah ok, this looks like what I'm looking for
(binding [*print-namespace-maps* false]
(str (z/node (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}"))))
so (-> zloc z/root z/node str)
yes
thank you!
probably the print-namespace-maps binding isnt' necessary here
as rewrite-clj won't change the node representation
yeah I think I can drop that now
now I'll have to go back and check all the places I'm using z/sexpr, I think in most cases I intended to do (-> value z/node str)