Add tooling API

This commit is contained in:
Peter Taoussanis 2013-06-17 21:59:52 +07:00
parent a5c986672d
commit 4326da0ae5
4 changed files with 57 additions and 8 deletions

View file

@ -2,10 +2,10 @@ Current [semantic](http://semver.org/) version:
```clojure
[com.taoensso/nippy "1.2.1"] ; Stable
[com.taoensso/nippy "2.0.0-alpha8"] ; Development (notes below)
[com.taoensso/nippy "2.0.0-alpha9"] ; Development (notes below)
```
2.x adds pluggable compression, crypto support (also pluggable), an improved API (including much better error messages), and hugely improved performance. It **is backwards compatible**, but please note that the old `freeze-to-bytes`/`thaw-from-bytes` API has been **deprecated** in favor of `freeze`/`thaw`. **PLEASE REPORT ANY PROBLEMS!**
v2 adds pluggable compression, crypto support (also pluggable), an improved API (including much better error messages), easier integration into other tools/libraries, and hugely improved performance. It **is backwards compatible**, but please note that the old `freeze-to-bytes`/`thaw-from-bytes` API has been **deprecated** in favor of `freeze`/`thaw`. **PLEASE REPORT ANY PROBLEMS!**
# Nippy, a Clojure serialization library
@ -20,7 +20,8 @@ Nippy is an attempt to provide a reliable, high-performance **drop-in alternativ
* **Reader-fallback** for difficult/future types (including Clojure 1.4+ tagged literals).
* **Full test coverage** for every supported type.
* Fully pluggable **compression**, including built-in high-performance [Snappy](http://code.google.com/p/snappy/) compressor.
* Fully pluggable **encryption**, including built-in high-strength AES128 enabled with a single `:password [:salted "my-password"]` option. (2.0.0+)
* Fully pluggable **encryption**, including built-in high-strength AES128 enabled with a single `:password [:salted "my-password"]` option. (v2+)
* Utils for **easy integration into 3rd-party tools/libraries**. (v2+)
## Getting started
@ -103,7 +104,7 @@ Couldn't be simpler!
### Encryption (currently in **ALPHA**)
As of 2.0.0, Nippy also gives you **dead simple data encryption**. Add a single option to your usual freeze/thaw calls like so:
Nippy v2+ also gives you **dead simple data encryption**. Add a single option to your usual freeze/thaw calls like so:
```clojure
(nippy/freeze nippy/stress-data {:password [:salted "my-password"]}) ; Encrypt

View file

@ -1,4 +1,4 @@
(defproject com.taoensso/nippy "2.0.0-alpha8"
(defproject com.taoensso/nippy "2.0.0-alpha9"
:description "Clojure serialization library"
:url "https://github.com/ptaoussanis/nippy"
:license {:name "Eclipse Public License"

View file

@ -269,7 +269,8 @@
[^bytes ba & [{:keys [read-eval? password compressor encryptor legacy-opts]
:or {legacy-opts {:compressed? true}
compressor snappy-compressor
encryptor aes128-encryptor}}]]
encryptor aes128-encryptor}
:as opts}]]
(let [ex (fn [msg & [e]] (throw (Exception. (str "Thaw failed: " msg) e)))
try-thaw-data
@ -301,7 +302,8 @@
(and compressed? (not compressor))
(ex "Compressed data. Try again with compressor.")
(and encrypted? (not password))
(ex "Encrypted data. Try again with password.")
(if (::tools-thaw? opts) ::need-password
(ex "Encrypted data. Try again with password."))
:else (try (try-thaw-data data-ba head-meta)
(catch Exception _ (try-thaw-data ba nil))))
@ -383,4 +385,4 @@
:or {compressed? true}}]
(thaw ba {:legacy-opts {:compressed? compressed?}
:read-eval? read-eval?
:password nil}))
:password nil}))

View file

@ -0,0 +1,46 @@
(ns taoensso.nippy.tools
"Alpha - subject to change.
Utilities for third-party tools that want to add fully-user-configurable Nippy
support. Used by Carmine and Faraday."
{:author "Peter Taoussanis"}
(:require [taoensso.nippy :as nippy]
[taoensso.nippy.utils :as utils]))
(defrecord WrappedForFreezing [value opts])
(defn wrapped-for-freezing? [x] (instance? WrappedForFreezing x))
(defn wrap-for-freezing
"Wraps arg (any freezable data type) so that (tools/freeze <wrapped-arg>)
will freeze the arg using given options."
[value & [opts]] (WrappedForFreezing. value opts))
(defn freeze
"Like `nippy/freeze` but takes options from special argument wrapper when
present."
[x & [{:keys [default-opts]}]]
(if (wrapped-for-freezing? x)
(nippy/freeze (:value x) (or (:opts x) default-opts))
(nippy/freeze x default-opts)))
(comment (freeze (wrap-for-freezing "wrapped"))
(freeze "unwrapped"))
(defrecord EncryptedFrozen [ba])
(defn encrypted-frozen? [x] (instance? EncryptedFrozen x))
(def ^:dynamic *thaw-opts* nil)
(defmacro with-thaw-opts [opts & body] `(binding [*thaw-opts* ~opts] ~@body))
(defn thaw
"Like `nippy/thaw` but takes options from *thaw-opts* binding, and wraps
encrypted bytes for easy identification when no password has been provided
for decryption."
[ba & {:keys [default-opts]}]
(let [result (nippy/thaw ba (merge (or *thaw-opts* default-opts)
{:taoensso.nippy/tools-thaw? true}))]
(if (= result :taoensso.nippy/need-password)
(EncryptedFrozen. ba)
result)))
(comment (thaw (nippy/freeze "c" {:password [:cached "p"]}))
(with-thaw-opts {:password [:cached "p"]}
(thaw (nippy/freeze "c" {:password [:cached "p"]}))))