This repository has been archived by the owner on Jul 11, 2019. It is now read-only.
forked from immutant/immutant
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fressian.clj
79 lines (70 loc) · 3.59 KB
/
fressian.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
;; Copyright 2014-2017 Red Hat, Inc, and individual contributors.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
(ns immutant.codecs.fressian
"Provides support for using Fressian as an Immutant codec."
(:require [immutant.codecs :refer [decode-error make-codec
register-codec]]
[immutant.internal.util :refer [kwargs-or-map->raw-map
try-resolve
try-resolve-throw]]
[immutant.internal.options :refer [set-valid-options!
validate-options]])
(:import java.nio.ByteBuffer))
(defn ^:internal ^:no-doc fressian-codec
[{:keys [name content-type read-handlers write-handlers]
:or {name :fressian content-type "application/fressian"}}]
(let [fressian-write (try-resolve-throw `clojure.data.fressian/write
"add org.clojure/data.fressian to your dependencies.")
fressian-read (try-resolve 'clojure.data.fressian/read)]
(make-codec
:name name
:content-type content-type
:type :bytes
:encode (fn [data]
(let [^ByteBuffer encoded (apply fressian-write data :footer? true
(if write-handlers [:handlers write-handlers]))
bytes (byte-array (.remaining encoded))]
(.get encoded bytes)
bytes))
:decode (fn [data]
(try
(and data (apply fressian-read data
(if read-handlers [:handlers read-handlers])))
(catch Throwable e
(throw (decode-error :fressian data e))))))))
(defn register-fressian-codec
"Creates and registers a codec that can be used to encode to/decode from Fressian.
To use vanilla Fressian, call this wih no options and use :fressian
when passing an encoding to functions that take such.
If you need to provide custom handlers, see the
[Fressian wiki](https://github.com/clojure/data.fressian/wiki/Creating-custom-handlers)
for more information on creating them. Note that custom handlers are
*not* merged with the default handlers - you are responsible for
that (as shown in the linked example).
You must add `org.clojure/data.fressian` as a dependency.
options can be a map or kwargs, with these valid keys [default]:
* :name - the name of the encoding [:fressian]
* :content-type - the content type for the encoding [\"application/fressian\"]
* :write-handlers - the full set of handlers to use for writing. If not
provided, the built-in Fressian defaults are used [nil]
* :read-handlers the full set of handlers to use for reading. If not
provided, the built-in Fressian defaults are used [nil]"
[& options]
(-> options
kwargs-or-map->raw-map
(validate-options register-fressian-codec)
fressian-codec
register-codec))
(set-valid-options! register-fressian-codec #{:name :content-type :type
:read-handlers :write-handlers})