lancepantz / clj-yaml

YAML encoding and decoding for Clojure via SnakeYAML
Other
91 stars 52 forks source link

can deserialize a Set, but can't serialize a Set #11

Open trevor opened 11 years ago

trevor commented 11 years ago
;; works:

(def typed-data-yaml "
the-bin: !!binary 0101")

(clj-yaml.core/parse-string typed-data-yaml)
;= {:the-bin #<byte[] [B@61911e64>}

(clj-yaml.core/generate-string
  (clj-yaml.core/parse-string typed-data-yaml)
  :dumper-options {:flow-style :block})
;= "the-bin: !!binary |-\n  0101\n"

;; generate-string creates a sequence instead of a set:

(def set-yaml "
--- !!set
? Mark McGwire
? Sammy Sosa
? Ken Griff")

(clj-yaml.core/parse-string set-yaml)
;= #{"Mark McGwire" "Ken Griff" "Sammy Sosa"}

(clj-yaml.core/generate-string
  (clj-yaml.core/parse-string set-yaml)
  :dumper-options {:flow-style :block})
;= "- Mark McGwire\n- Ken Griff\n- Sammy Sosa\n"

(clj-yaml.core/parse-string
  (clj-yaml.core/generate-string
    (clj-yaml.core/parse-string set-yaml)
    :dumper-options {:flow-style :block}))
;= ("Mark McGwire" "Ken Griff" "Sammy Sosa")
trevor commented 11 years ago

This allows for Sets that contain numbers only, or strings only:

  clojure.lang.PersistentHashSet
  (encode [data]
    (java.util.HashSet. data))

  clojure.lang.PersistentTreeSet
  (encode [data]
    (java.util.TreeSet. data))
trevor commented 11 years ago

… but this is better:

clojure.lang.IPersistentSet
(encode [data]
  (into #{}
    (map encode data)))

example (with modified fn's):

=> (println (yaml-dump ["y" #{"d" 'b/c :a 2 [3 4 {5 6 :x [7 #{}]}]} "m" nil "n"]))
---
- y
- !!set
  a: null
  2: null
  ? - 3
    - 4
    - 5: 6
      x:
      - 7
      - !!set {}
  : null
  d: null
  ? !!clojure.lang.Symbol
    name: c
    namespace: b
  : null
- m
- null
- n
...