JSON-Clojure.json.clj 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. (declare to-json)
  2. (defn- json-property
  3. ([name value column] [:property (str name) (to-json value column)])
  4. ([column row] [:property (.name column) (to-json (.value row column) column)]))
  5. (defn- json-object
  6. ([pairs column] [:object (map (fn [[n v]] (json-property n v column)) pairs)])
  7. ([row] [:object (map #(json-property % row) COLUMNS)]))
  8. (defn- json-array
  9. ([elements column] [:array (map #(to-json % column) elements)])
  10. ([rows] [:array (map json-object rows)]))
  11. (defn- to-json [value column]
  12. (cond
  13. (nil? value) [:nil]
  14. (or (number? value)
  15. (instance? Boolean value)) [:value value column]
  16. (instance? java.util.Map value) (json-object (seq value) column)
  17. (.isArray (.getClass value)) (json-array (seq value) column)
  18. :else [:string value column]))
  19. (defn- format [value column] (.formatValue FORMATTER value column))
  20. (defn- escape-chars [v] (com.intellij.openapi.util.text.StringUtil/escapeStringCharacters v))
  21. (defn- output [& strings] (doseq [s (flatten strings)] (.append OUT s)))
  22. (defn- output-indent [level] (output (repeat level " ")))
  23. (defn- output-json [[type & args] level]
  24. (case type
  25. :nil (output "null")
  26. :plain (let [[text] args] (output text))
  27. :value (let [[v c] args] (output (format v c)))
  28. :string (let [[v c] args] (output "\"" (escape-chars (format v c)) "\""))
  29. :property (let [[n v] args] (output "\"" (escape-chars n) "\": ") (output-json v level))
  30. :object (let [[props] args] (output-json [:nested "{" props "}"] level))
  31. :array (let [[values] args] (output-json [:nested "[" values "]"] level))
  32. :nested (let [[lpar values rpar] args]
  33. (output lpar)
  34. (when (seq values)
  35. (output "\n")
  36. (doseq [v (interpose [:plain ",\n"] values)]
  37. (when-not (= :plain (first v))
  38. (output-indent (inc level)))
  39. (output-json v (inc level)))
  40. (output "\n")
  41. (output-indent level))
  42. (output rpar))))
  43. (output-json (json-array ROWS) 0)