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 ```clojure
[com.taoensso/nippy "1.2.1"] ; Stable [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 # 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). * **Reader-fallback** for difficult/future types (including Clojure 1.4+ tagged literals).
* **Full test coverage** for every supported type. * **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 **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 ## Getting started
@ -103,7 +104,7 @@ Couldn't be simpler!
### Encryption (currently in **ALPHA**) ### 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 ```clojure
(nippy/freeze nippy/stress-data {:password [:salted "my-password"]}) ; Encrypt (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" :description "Clojure serialization library"
:url "https://github.com/ptaoussanis/nippy" :url "https://github.com/ptaoussanis/nippy"
:license {:name "Eclipse Public License" :license {:name "Eclipse Public License"

View file

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