[new] Refactor tools ns, embed dynamic *freeze-opts* in wrappers
This commit is contained in:
parent
064015e874
commit
3ac06b6c87
1 changed files with 54 additions and 40 deletions
|
|
@ -1,60 +1,74 @@
|
|||
(ns taoensso.nippy.tools
|
||||
"Utils for 3rd-party tools that want to add user-configurable Nippy support.
|
||||
"Utils for community tools that want to add user-configurable Nippy support.
|
||||
Used by Carmine, Faraday, etc."
|
||||
(:require [taoensso.nippy :as nippy]))
|
||||
|
||||
(def ^:dynamic *freeze-opts* nil)
|
||||
(def ^:dynamic *thaw-opts* nil)
|
||||
|
||||
(defmacro with-freeze-opts [opts & body] `(binding [*freeze-opts* ~opts] ~@body))
|
||||
(defmacro with-thaw-opts [opts & body] `(binding [*thaw-opts* ~opts] ~@body))
|
||||
(defn ^:no-doc -merge-opts
|
||||
"Private, implementation detail."
|
||||
([x y ] (if x (conj x y) y))
|
||||
([x y z] (-merge-opts (-merge-opts x y) z)))
|
||||
|
||||
(do
|
||||
(defmacro with-freeze-opts [opts & body] `(binding [*freeze-opts* ~opts ] ~@body))
|
||||
(defmacro with-freeze-opts+ [opts & body] `(binding [*freeze-opts* (-merge-opts *freeze-opts* ~opts)] ~@body))
|
||||
(defmacro with-thaw-opts [opts & body] `(binding [*thaw-opts* ~opts ] ~@body))
|
||||
(defmacro with-thaw-opts+ [opts & body] `(binding [*thaw-opts* (-merge-opts *thaw-opts* ~opts)] ~@body)))
|
||||
|
||||
(deftype WrappedForFreezing [val opts])
|
||||
(defn wrapped-for-freezing? [x] (instance? WrappedForFreezing x))
|
||||
(defn wrap-for-freezing
|
||||
"Ensures that given arg (any freezable data type) is wrapped so that
|
||||
(tools/freeze <wrapped-arg>) will serialize as
|
||||
(nippy/freeze <unwrapped-arg> <opts>).
|
||||
|
||||
See also `nippy.tools/freeze`, `nippy.tools/thaw`."
|
||||
([x ] (wrap-for-freezing x nil))
|
||||
([x opts]
|
||||
(if (instance? WrappedForFreezing x)
|
||||
(let [^WrappedForFreezing x x]
|
||||
(if (= (.-opts x) opts)
|
||||
x
|
||||
(WrappedForFreezing. (.-val x) opts)))
|
||||
(WrappedForFreezing. x opts))))
|
||||
(let [-merge-opts -merge-opts]
|
||||
(defn wrap-for-freezing
|
||||
"Captures (merge `tools/*thaw-opts*` `wrap-opts`), and returns
|
||||
the given argument in a wrapped form so that `tools/freeze` will
|
||||
use the captured options when freezing the wrapper argument.
|
||||
|
||||
(defn freeze
|
||||
"Like `nippy/freeze` but uses as opts the following merged in order of
|
||||
ascending preference:
|
||||
See also `tools/freeze`."
|
||||
([x ] (wrap-for-freezing x nil))
|
||||
([x wrap-opts]
|
||||
(let [captured-opts (-merge-opts *freeze-opts* wrap-opts)] ; wrap > dynamic
|
||||
(if (instance? WrappedForFreezing x)
|
||||
(let [^WrappedForFreezing x x]
|
||||
(if (= (.-opts x) captured-opts)
|
||||
x
|
||||
(WrappedForFreezing. (.-val x) captured-opts)))
|
||||
(WrappedForFreezing. x captured-opts))))))
|
||||
|
||||
- Optional `default-opts` arg given to this fn (default nil).
|
||||
- Optional `*freeze-opts*` dynamic value (default nil).
|
||||
- Optional opts provided to `wrap-for-freezing` (default nil)."
|
||||
(let [-merge-opts -merge-opts]
|
||||
(defn freeze
|
||||
"Like `nippy/freeze` but uses as options the following, merged in
|
||||
order of ascending preference:
|
||||
|
||||
([x ] (freeze x nil))
|
||||
([x default-opts]
|
||||
(let [default-opts (get default-opts :default-opts default-opts) ; For back compatibility
|
||||
merged-opts (conj (or default-opts {}) *freeze-opts*)]
|
||||
1. `default-opts` given to this fn (default nil).
|
||||
2. `tools/*freeze-opts*` dynamic value (default nil).
|
||||
3. Opts captured by `tools/wrap-for-freezing` (default nil).
|
||||
|
||||
(if (instance? WrappedForFreezing x)
|
||||
(let [^WrappedForFreezing x x]
|
||||
(nippy/freeze (.-val x) (conj merged-opts (.-opts x))))
|
||||
(nippy/freeze x merged-opts)))))
|
||||
See also `tools/wrap-for-freezing`."
|
||||
([x ] (freeze x nil))
|
||||
([x default-opts]
|
||||
(let [default-opts (get default-opts :default-opts default-opts) ; Back compatibility
|
||||
active-opts (-merge-opts default-opts *freeze-opts*)] ; dynamic > default
|
||||
|
||||
(defn thaw
|
||||
"Like `nippy/thaw` but uses as opts the following merged in order of
|
||||
ascending preference:
|
||||
(if (instance? WrappedForFreezing x)
|
||||
(let [^WrappedForFreezing x x]
|
||||
(nippy/freeze (.-val x) (-merge-opts active-opts (.-opts x)))) ; captured > active!
|
||||
(nippy/freeze x active-opts))))))
|
||||
|
||||
- Optional `default-opts` arg given to this fn (default nil).
|
||||
- Optional `*thaw-opts*` dynamic value (default nil)."
|
||||
(let [-merge-opts -merge-opts]
|
||||
(defn thaw
|
||||
"Like `nippy/thaw` but uses as options the following, merged in
|
||||
order of ascending preference:
|
||||
|
||||
([ba ] (thaw ba nil))
|
||||
([ba default-opts]
|
||||
(let [default-opts (get default-opts :default-opts default-opts) ; For back compatibility
|
||||
merged-opts (conj (or default-opts {}) *thaw-opts*)]
|
||||
(nippy/thaw ba merged-opts))))
|
||||
1. `default-opts` given to this fn (default nil).
|
||||
2. `tools/*thaw-opts*` dynamic value (default nil)."
|
||||
([ba ] (thaw ba nil))
|
||||
([ba default-opts]
|
||||
(let [default-opts (get default-opts :default-opts default-opts) ; Back compatibility
|
||||
active-opts (-merge-opts default-opts *thaw-opts*)] ; dynamic > default
|
||||
|
||||
(nippy/thaw ba active-opts)))))
|
||||
|
||||
(comment (thaw (freeze (wrap-for-freezing "wrapped"))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue