forked from owainlewis/yaml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
writer.clj
87 lines (79 loc) · 2.43 KB
/
writer.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
(ns yaml.writer
(:require [flatland.ordered.set :refer [ordered-set]]
[flatland.ordered.map :refer [ordered-map]])
(:import (org.yaml.snakeyaml Yaml DumperOptions DumperOptions$FlowStyle DumperOptions$ScalarStyle)))
(def flow-styles
{:auto DumperOptions$FlowStyle/AUTO
:block DumperOptions$FlowStyle/BLOCK
:flow DumperOptions$FlowStyle/FLOW})
(def scalar-styles
{:double-quoted DumperOptions$ScalarStyle/DOUBLE_QUOTED
:single-quoted DumperOptions$ScalarStyle/SINGLE_QUOTED
:literal DumperOptions$ScalarStyle/LITERAL
:folded DumperOptions$ScalarStyle/FOLDED
:plain DumperOptions$ScalarStyle/PLAIN})
(defn- make-dumper-options
[{:keys [flow-style scalar-style split-lines width]}]
(let [options (DumperOptions.)]
(when flow-style
(.setDefaultFlowStyle options (flow-styles flow-style)))
(when scalar-style
(.setDefaultScalarStyle options (scalar-styles scalar-style)))
(when (some? split-lines)
(.setSplitLines options split-lines))
(when (some? width)
(.setWidth options width))
options))
(defn make-yaml
[& {:keys [dumper-options]}]
(if dumper-options
(Yaml. ^DumperOptions (make-dumper-options dumper-options))
(Yaml.)))
(defn- keyword->string
[key]
(if (nil? (namespace key))
(name key)
(str (namespace key) "/" (name key))))
(defprotocol YAMLWriter
(encode [data]))
(extend-protocol YAMLWriter
flatland.ordered.set.OrderedSet
(encode [data]
(java.util.LinkedHashSet.
^flatland.ordered.set.OrderedSet
(into (ordered-set)
(map encode data))))
flatland.ordered.map.OrderedMap
(encode [data]
(java.util.LinkedHashMap.
^flatland.ordered.map.OrderedMap
(into (ordered-map)
(for [[k v] data]
[(encode k) (encode v)]))))
clojure.lang.IPersistentMap
(encode [data]
(into {}
(for [[k v] data]
[(encode k) (encode v)])))
clojure.lang.IPersistentSet
(encode [data]
(into #{}
(map encode data)))
clojure.lang.IPersistentCollection
(encode [data]
(map encode data))
clojure.lang.PersistentTreeMap
(encode [data]
(into (sorted-map)
(for [[k v] data]
[(encode k) (encode v)])))
clojure.lang.Keyword
(encode [data]
(keyword->string data))
Object
(encode [data] data)
nil
(encode [data] data))
(defn generate-string [data & opts]
(.dump ^Yaml (apply make-yaml opts)
^Object (encode data)))