(relative-include "zlib_helper.h") (add-cflag "-lz") (doc ZLib "is a high-level wrapper around [zlib](https://zlib.net/). ## Installation ```clojure (load \"git@git.veitheller.de:carpentry/zlib.git@0.0.2\") ``` ## Usage The `ZLib` module provides only two functions, [`inflate`](#inflate) and [`deflate`](#deflate). These functions work in tandem to provide you with data compression. ```clojure ; deflate returns a Result of either binary data or an error message (let [deflated (ZLib.deflate \"mystring\")] (match deflated ; inflate returns a Result of either a string or an error message (Success bin) (println* &(inflate bin)) (Error msg) (IO.errorln &msg))) ``` Because it’s a `Result` type, we can apply combinators to it. ```clojure (=> (ZLib.deflate \"mystring\") (Result.and-then &ZLib.inflate) (Result.map-error &(fn [msg] (do (println* &msg) msg))) ) ``` You can also choose different levels of compression using `inflate-with`. The levels are defined in [`ZLib.ZLevel`](#ZLevel), and are `NoCompression`, `BestSpeed`, `BestCompression`, and `DefaultCompression`, which is, well, the default.") ; i tried doing this in carp, but it’s a bit of a pain to wrap the API ; idiomatically, so for now you’ll only get regular inflation and deflation (defmodule ZLib (register-type ZBytes [ len Int bytes String ]) (hidden ZBytes) (register-type ZRes) (defmodule ZRes (register ok? (Fn [&ZRes] Bool) "ZRes_is_ok") (register bytes (Fn [ZRes] ZLib.ZBytes) "ZRes_bytes") (register str (Fn [ZRes] String) "ZRes_str") (register err (Fn [ZRes] String) "ZRes_err") ) (hidden ZRes) (deftype ZLevel (NoCompression []) (BestSpeed []) (BestCompression []) (DefaultCompression []) ) (defmodule ZLevel (defn to-int [l] (match l (NoCompression) 0 (BestSpeed) 1 (BestCompression) 9 (DefaultCompression) -1))) (doc ZLevel "is a type used in conjunction with [`deflate-with`](#deflate-with). It controls the compression level. The constructors are `NoCompression`, `BestSpeed`, `BestCompression`, and `DefaultCompression`, which is, well, the default.") (private inflate-) (hidden inflate-) (register inflate- (Fn [ZLib.ZBytes] ZRes) "ZLib_inflate_c") (doc inflate "takes a bytes object `s` and returns a `Result`. The `Result` will be a `Success` containing the inflated string if all goes well, and an `Error` returning an error message otherwise.") (defn inflate [s] (let [r (inflate- s)] (if (ZRes.ok? &r) (Result.Success (ZRes.str r)) (Result.Error (ZRes.err r))))) (private deflate-) (hidden deflate-) (register deflate- (Fn [&String Int] ZRes) "ZLib_deflate_c") (doc deflate-with "takes a bytes object `s`, a `Zlevel` `level` and returns a `Result`. The `Result` will be a `Success` containing the deflated bytes if all goes well, and an `Error` returning an error message otherwise.") (defn deflate-with [s level] (let [r (deflate- s (ZLevel.to-int level))] (if (ZRes.ok? &r) (Result.Success (ZRes.bytes r)) (Result.Error (ZRes.err r))))) (doc deflate "takes a bytes object `s` and returns a `Result`. The `Result` will be a `Success` containing the deflated bytes if all goes well, and an `Error` returning an error message otherwise. It is equivalent to calling [`deflate-with`](#deflate-with) with `(ZLevel.DefaultCompression)`.") (defn deflate [s] (deflate-with s (ZLevel.DefaultCompression))) )