Fork me on GitHub

0.0.3 release after a LONG time is out for A tiny library converting OpenAPI spec to #reitit routes. This is suitable for making servers. Hopefully its of use to some folks! 😄

❤️ 30
👍 16
👏 10
🎉 14

This blog post was a nice rabbit hole to fall into! Many things there speak of the challenges I have right now 😄


Got my Java JSON library, heavily inspired by data.json and elm's json package, minimally documented with some examples. It is usable from Clojure, but tbh you should prefer an existing option. This is mostly targeting ergonomics for the typed side of the world

🎉 12

Example of clojure usage - does work. Just, again, not what I was designing for

(ns json
  (:import (dev.mccue.json Json JsonReadException)
           ( JsonArrayHandler JsonObjectHandler JsonValueHandler)
           ( StringReader))
  (:refer-clojure :exclude [read read-string]))

(declare value-handler)

(defn object-handler
  (let [object (transient {})]
    (reify JsonObjectHandler
      (onField [_ field]
        (value-handler #(assoc! object field %)))
      (onObjectEnd [_]
        (cb (persistent! object))))))

(defn array-handler
  (let [array (transient [])]
    (reify JsonArrayHandler
      (onObjectStart [_]
        (object-handler #(conj! array %)))
      (onArrayStart [_]
        (array-handler #(conj! array %)))
      (onNumber [_ number]
        (conj! array
               (if (.isIntegral number)
                 (.bigIntegerValue number)
                 (.bigDecimalValue number))))
      (onString [_ string]
        (conj! array string))
      (onNull [_]
        (conj! array nil))
      (onTrue [_]
        (conj! array true))
      (onFalse [_]
        (conj! array false))
      (onArrayEnd [_]
        (cb (persistent! array))))))

(defn value-handler
  (reify JsonValueHandler
    (onObjectStart [_]
      (object-handler cb))
    (onArrayStart [_]
      (array-handler cb))
    (onNumber [_ number]
      (cb (if (.isIntegral number)
            (.bigIntegerValue number)
            (.bigDecimalValue number))))
    (onString [_ string]
      (cb string))
    (onNull [_]
      (cb nil))
    (onTrue [_]
      (cb true))
    (onFalse [_]
      (cb false))))

(defn read
  (let [not-read (Object.)
        result (volatile! not-read)]
      (value-handler #(vreset! result %)))
    (let [result @result]
      (when (= not-read result)
        (throw (JsonReadException/unexpectedEOF)))

(defn read-string
  (read (StringReader. s)))