Files
zlib/zlib.carp
2022-01-27 11:55:55 +01:00

115 lines
3.4 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(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 its 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 its a bit of a pain to wrap the API
; idiomatically, so for now youll 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)))
)