-
Notifications
You must be signed in to change notification settings - Fork 25
/
serializers.cljc
102 lines (89 loc) · 4.05 KB
/
serializers.cljc
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(ns konserve.serializers
(:require #?(:clj [clj-cbor.core :as cbor])
#?(:clj [clojure.data.fressian :as fress] :cljs [fress.api :as fress])
[konserve.protocols :refer [PStoreSerializer -serialize -deserialize]]
[incognito.fressian :refer [incognito-read-handlers incognito-write-handlers]]
[incognito.edn :refer [read-string-safe]])
#?(:clj (:import [org.fressian.handlers WriteHandler ReadHandler])))
#?(:clj
(defrecord CBORSerializer [codec]
PStoreSerializer
(-deserialize [_ read-handlers bytes]
(when-not (empty? @read-handlers)
(throw (ex-info "Read handlers not supported yet." {:type :handlers-not-supported-yet})))
(cbor/decode codec bytes))
(-serialize [_ bytes write-handlers val]
(when-not (empty? @write-handlers)
(throw (ex-info "Write handlers not supported yet." {:type :handlers-not-supported-yet})))
(cbor/encode codec bytes val))))
#?(:clj
(defn cbor-serializer
([] (cbor-serializer {} {}))
([read-handlers write-handlers]
(let [codec (cbor/cbor-codec
:write-handlers (merge cbor/default-write-handlers write-handlers)
:read-handlers (merge cbor/default-read-handlers read-handlers))]
(map->CBORSerializer {:codec codec})))))
(defrecord FressianSerializer [custom-read-handlers custom-write-handlers]
#?@(:cljs (INamed ;clojure.lang.Named
(-name [_] "FressianSerializer")
(-namespace [_] "konserve.serializers")))
PStoreSerializer
(-deserialize [_ read-handlers bytes]
(let [handlers #?(:cljs (merge custom-read-handlers (incognito-read-handlers read-handlers))
:clj (-> (merge fress/clojure-read-handlers
custom-read-handlers
(incognito-read-handlers read-handlers))
fress/associative-lookup))]
(fress/read bytes :handlers handlers)))
(-serialize [_ bytes write-handlers val]
(let [handlers #?(:clj (-> (merge
fress/clojure-write-handlers
custom-write-handlers
(incognito-write-handlers write-handlers))
fress/associative-lookup
fress/inheritance-lookup)
:cljs (merge custom-write-handlers
(incognito-write-handlers write-handlers)))]
#?(:clj (let [writer (fress/create-writer bytes :handlers handlers)]
(fress/write-object writer val))
:cljs (fress/write val :handlers handlers)))))
(defn fressian-serializer
([] (fressian-serializer {} {}))
([read-handlers write-handlers] (map->FressianSerializer {:custom-read-handlers read-handlers
:custom-write-handlers write-handlers})))
(defrecord StringSerializer []
#?@(:cljs (INamed
(-name [_] "StringSerializer")
(-namespace [_] "konserve.serializers")))
PStoreSerializer
(-deserialize [_ read-handlers s]
(read-string-safe @read-handlers s))
(-serialize [_ output-stream _ val]
#?(:cljs (pr-str val)
:clj (binding [clojure.core/*out* output-stream]
(pr val)))))
(defn string-serializer []
(map->StringSerializer {}))
(defn construct->class [m]
(->> (map (fn [[k v]] [#?(:clj (class v)
:cljs (type v)) k]) m)
(into {})))
(def byte->serializer
{0 (string-serializer)
1 (fressian-serializer)
#?@(:clj [2 (cbor-serializer)])})
(def serializer-class->byte
(construct->class byte->serializer))
(defn construct->keys [m]
(->> (map (fn [[_ v]]
[#?(:clj (-> v class .getSimpleName keyword)
:cljs (-> v name keyword)) v]) m)
(into {})))
(def key->serializer
(construct->keys byte->serializer))
(defn construct->byte [m n]
(->> (map (fn [[k0 v0] [k1 v1]] [k0 k1]) m n)
(into {})))
(def byte->key
(construct->byte byte->serializer key->serializer))