diff --git a/jolt-core/clojure/core/50-io.clj b/jolt-core/clojure/core/50-io.clj index 733c3b0..aceff06 100644 --- a/jolt-core/clojure/core/50-io.clj +++ b/jolt-core/clojure/core/50-io.clj @@ -156,3 +156,24 @@ (if (keyword? t) t (type x))))) (defmethod print-dup :default [o w] (print-method o w)) + +;; Cold tagged-type renderings, migrated from the host renderer (the hot +;; types — numbers, strings, symbols, collections — stay native). Each is the +;; exact output the host branch produced. +(defmethod print-method :jolt/uuid [u w] + (.write w (str "#uuid \"" (get u :str) "\"")) + nil) + +(defmethod print-method :jolt/regex [re w] + (.write w (str "#\"" (get re :source) "\"")) + nil) + +;; a transient's get IS the dispatched collection lookup — read the wrapper's +;; own :kind field with the host accessor (same trap as sorted colls). +(defmethod print-method :jolt/transient [t w] + (.write w (str "#")) + nil) + +(defmethod print-method :jolt/chan [c w] + (.write w "#") + nil) diff --git a/src/jolt/core.janet b/src/jolt/core.janet index d1102a3..571bd98 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -1560,13 +1560,9 @@ 10 "newline" 32 "space" 9 "tab" 13 "return" 12 "formfeed" 8 "backspace" 0 "nul" (char->string v)))) - (regex? v) (do (buffer/push-string buf "#\"") (buffer/push-string buf (v :source)) (buffer/push-string buf "\"")) (number? v) (buffer/push-string buf (fmt-number v)) (and (struct? v) (= :symbol (v :jolt/type))) (buffer/push-string buf (if (v :ns) (string (v :ns) "/" (v :name)) (v :name))) - (and (struct? v) (= :jolt/uuid (v :jolt/type))) - (do (buffer/push-string buf "#uuid \"") (buffer/push-string buf (v :str)) - (buffer/push-string buf "\"")) (and (struct? v) (= :jolt/inst (v :jolt/type))) (do (buffer/push-string buf "#inst \"") (buffer/push-string buf (inst->rfc3339 v)) (buffer/push-string buf "\"")) @@ -1581,8 +1577,6 @@ (lazy-seq? v) (pr-render-seq buf (realize-for-iteration v) "(" ")") (set? v) (pr-render-seq buf (phs-seq v) "#{" "}") (phm? v) (pr-render-pairs buf (phm-entries v)) - (core-transient? v) (buffer/push-string buf (string "#")) - (and (table? v) (= :jolt/chan (get v :jolt/type))) (buffer/push-string buf "#") (pvec? v) (pr-render-seq buf (pv->array v) "[" "]") (plist? v) (pr-render-seq buf (pl->array v) "(" ")") (and (table? v) (get v :jolt/deftype)) @@ -1597,6 +1591,15 @@ (tuple? v) (pr-render-seq buf v "[" "]") # mutable mode: arrays are vectors -> print with [] (else lists -> ()) (array? v) (if mutable? (pr-render-seq buf v "[" "]") (pr-render-seq buf v "(" ")")) + # Any remaining TAGGED value dispatches through print-method when the + # hook is wired: the io tier owns the cold renderings (uuid, regex, + # transient, channel — branches that used to live here), and user + # defmethods on any :jolt/* tag fire from inside nested values. Before + # the overlay loads (init-time error messages) these fall through to + # the raw pairs view below. + (and print-method-cb (get v :jolt/type) + (print-method-cb v (fn [piece] (buffer/push-string buf piece)))) + nil (struct? v) (pr-render-pairs buf (pairs v)) (table? v) (pr-render-pairs buf (pairs v)) true (buffer/push-string buf (string v))))) diff --git a/test/spec/io-spec.janet b/test/spec/io-spec.janet index c16cc4b..6a2b138 100644 --- a/test/spec/io-spec.janet +++ b/test/spec/io-spec.janet @@ -95,3 +95,20 @@ "(let [w (StringWriter.)] (.write w \"a\") (.append w \\b) (.toString w))"] ["methods table inspectable" "true" "(do (defrecord Pt [x y]) (defmethod print-method (quote user.Pt) [r w] r) (contains? (methods print-method) (quote user.Pt)))"]) + +# Cold tagged-type printing now lives in io-tier defmethods (the host +# renderer dispatches any remaining :jolt/* tagged value through the +# print-method hook). Outputs unchanged from the old host branches; any +# tagged type is now user-overridable, atoms included. +(defspec "io / cold tagged types via print-method" + ["uuid" "\"#uuid \\\"b6883c0a-0342-4007-9966-bc2dfa6b109e\\\"\"" + "(pr-str (parse-uuid \"b6883c0a-0342-4007-9966-bc2dfa6b109e\"))"] + ["uuid nested" "\"[#uuid \\\"b6883c0a-0342-4007-9966-bc2dfa6b109e\\\"]\"" + "(pr-str [(parse-uuid \"b6883c0a-0342-4007-9966-bc2dfa6b109e\")])"] + ["regex" "\"#\\\"a+b\\\"\"" "(pr-str #\"a+b\")"] + ["transient vector" "\"#\"" "(pr-str (transient [1]))"] + ["transient map" "\"#\"" "(pr-str (transient {:a 1}))"] + ["atom override fires nested" "\"{:a #atom[7]}\"" + "(do (defmethod print-method :jolt/atom [a w] (.write w (str \"#atom[\" (deref a) \"]\"))) (pr-str {:a (atom 7)}))"] + ["uuid through str unchanged" "\"b6883c0a-0342-4007-9966-bc2dfa6b109e\"" + "(str (parse-uuid \"b6883c0a-0342-4007-9966-bc2dfa6b109e\"))"])