added docs
This commit is contained in:
248
docs/RESP.html
Normal file
248
docs/RESP.html
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<div class="logo">
|
||||||
|
<a href="http://github.com/carp-lang/Carp">
|
||||||
|
<img src="logo.png">
|
||||||
|
</a>
|
||||||
|
<div class="title">
|
||||||
|
redis
|
||||||
|
</div>
|
||||||
|
<div class="index">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="RESP.html">
|
||||||
|
RESP
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="Redis.html">
|
||||||
|
Redis
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1>
|
||||||
|
RESP
|
||||||
|
</h1>
|
||||||
|
<div class="module-description">
|
||||||
|
<p>is a wrapper around the <a href="https://redis.io/topics/protocol">Redis Serialization
|
||||||
|
Protocol</a>. You can create all types—though
|
||||||
|
creating arrays is a little unsightly due to the absence of recursive types—,
|
||||||
|
stringify the built types into strings using <a href="#str"><code>str</code></a>, and decoding from
|
||||||
|
the string protocol using <a href="#from-string"><code>from-string</code></a>.</p>
|
||||||
|
<p>If you want your types to be supported when encoding, you’ll have to implement
|
||||||
|
the interface <code>to-redis</code>, the signature of which is <code>(Fn [a] RESP))</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#Arr">
|
||||||
|
<h3 id="Arr">
|
||||||
|
Arr
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Array String)] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>creates a <code>Arr</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#Err">
|
||||||
|
<h3 id="Err">
|
||||||
|
Err
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [String] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>creates a <code>Err</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#Integer">
|
||||||
|
<h3 id="Integer">
|
||||||
|
Integer
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [Int] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>creates a <code>Integer</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#Null">
|
||||||
|
<h3 id="Null">
|
||||||
|
Null
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>creates a <code>Null</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#Str">
|
||||||
|
<h3 id="Str">
|
||||||
|
Str
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [String] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>creates a <code>Str</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#copy">
|
||||||
|
<h3 id="copy">
|
||||||
|
copy
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Ref RESP a)] RESP)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>copies a <code>RESP</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#from-string">
|
||||||
|
<h3 id="from-string">
|
||||||
|
from-string
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
defn
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Ref String a)] (Result RESP String))
|
||||||
|
</p>
|
||||||
|
<pre class="args">
|
||||||
|
(from-string s)
|
||||||
|
</pre>
|
||||||
|
<p class="doc">
|
||||||
|
<p>converts a RESP string into a <code>RESP</code> data structure.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#get-tag">
|
||||||
|
<h3 id="get-tag">
|
||||||
|
get-tag
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Ref RESP a)] Int)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>Gets the tag from a <code>RESP</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#prn">
|
||||||
|
<h3 id="prn">
|
||||||
|
prn
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
instantiate
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Ref RESP a)] String)
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>converts a <code>RESP</code> to a string.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#str">
|
||||||
|
<h3 id="str">
|
||||||
|
str
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
defn
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [(Ref RESP a)] String)
|
||||||
|
</p>
|
||||||
|
<pre class="args">
|
||||||
|
(str r)
|
||||||
|
</pre>
|
||||||
|
<p class="doc">
|
||||||
|
<p>converts a <code>RESP</code> to a string.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
5368
docs/Redis.html
Normal file
5368
docs/Redis.html
Normal file
File diff suppressed because it is too large
Load Diff
42
docs/redis_index.html
Normal file
42
docs/redis_index.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<a href="https://veitheller/git/carpentry/redis">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="" alt="Logo">
|
||||||
|
<div class="index">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="RESP.html">
|
||||||
|
RESP
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="Redis.html">
|
||||||
|
Redis
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
redis
|
||||||
|
</h1>
|
||||||
|
<p>is a collection of modules for talking
|
||||||
|
to Redis.</p>
|
||||||
|
<pre><code>(load "https://veitheller/git/carpentry/redis@master")
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
120
docs/style.css
Normal file
120
docs/style.css
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
html {
|
||||||
|
font-family: "Hasklig", "Lucida Console", monospace;
|
||||||
|
font-size: 1.0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0em 0em 0.5em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #f1f1f1;
|
||||||
|
padding: 10px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
padding: 1em;
|
||||||
|
position: fixed;
|
||||||
|
top: 1em;
|
||||||
|
right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.args {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
padding: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin: 3em auto auto auto;
|
||||||
|
width: 70%;
|
||||||
|
max-width: 650px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-description {
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-bottom: 3.5em;
|
||||||
|
border-bottom: 5px solid #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anchor {
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anchor:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.binder {
|
||||||
|
margin: 0em 0em 3.5em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sig {
|
||||||
|
font-family: "Hasklig", "Lucida Console", monospace;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: "Hasklig", "Lucida Console", monospace;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smaller screens */
|
||||||
|
@media only screen and (max-width: 1000px) {
|
||||||
|
.logo {
|
||||||
|
margin: 1em;
|
||||||
|
text-align: left;
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
position: inherit;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
.binder {
|
||||||
|
margin: 0em 0em 1.5em 0em;
|
||||||
|
}
|
||||||
|
.sig {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
(load "https://veitheller.de/git/carpentry/redis.git@master")
|
(load "redis.carp")
|
||||||
|
|
||||||
(defn main []
|
(defn main []
|
||||||
(match (Redis.open "127.0.0.1")
|
(match (Redis.open "127.0.0.1")
|
||||||
|
17
gendocs.carp
Normal file
17
gendocs.carp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
(load "redis.carp")
|
||||||
|
|
||||||
|
(Project.config "title" "redis")
|
||||||
|
(Project.config "docs-directory" "./docs/")
|
||||||
|
(Project.config "docs-logo" "")
|
||||||
|
(Project.config "docs-url" "https://veitheller/git/carpentry/redis")
|
||||||
|
(Project.config "docs-styling" "style.css")
|
||||||
|
(Project.config "docs-prelude" "is a collection of modules for talking
|
||||||
|
to Redis.
|
||||||
|
|
||||||
|
```
|
||||||
|
(load \"https://veitheller/git/carpentry/redis@master\")
|
||||||
|
```
|
||||||
|
")
|
||||||
|
|
||||||
|
(save-docs RESP Redis)
|
||||||
|
(quit)
|
50
redis.carp
50
redis.carp
@@ -12,7 +12,8 @@
|
|||||||
(defmodule RESP
|
(defmodule RESP
|
||||||
(use-all Array Int Maybe Pattern Result)
|
(use-all Array Int Maybe Pattern Result)
|
||||||
|
|
||||||
(def separator "\r\n")
|
(hidden c)
|
||||||
|
(private c)
|
||||||
(def c (prn &@&[@""]))
|
(def c (prn &@&[@""]))
|
||||||
|
|
||||||
(defn str [r]
|
(defn str [r]
|
||||||
@@ -23,6 +24,8 @@
|
|||||||
(Integer i) (fmt ":%d\r\n" i)
|
(Integer i) (fmt ":%d\r\n" i)
|
||||||
(Arr a) (fmt "*%d\r\n%s" (length &a) &(concat &a))))
|
(Arr a) (fmt "*%d\r\n%s" (length &a) &(concat &a))))
|
||||||
|
|
||||||
|
(hidden decode-bulk-string)
|
||||||
|
(private decode-bulk-string)
|
||||||
(defn decode-bulk-string [s]
|
(defn decode-bulk-string [s]
|
||||||
(if (starts-with? s "-1\r\n")
|
(if (starts-with? s "-1\r\n")
|
||||||
(Success (Null))
|
(Success (Null))
|
||||||
@@ -34,17 +37,22 @@
|
|||||||
(String.prefix-string &(join "\r\n" &(suffix-array &splt 1))
|
(String.prefix-string &(join "\r\n" &(suffix-array &splt 1))
|
||||||
(from-string l))))))))
|
(from-string l))))))))
|
||||||
|
|
||||||
|
(hidden agg)
|
||||||
|
(private agg)
|
||||||
(defn agg [els len]
|
(defn agg [els len]
|
||||||
(let-do [consumed 0
|
(let-do [consumed 0
|
||||||
clen 0]
|
clen 0]
|
||||||
(foreach [el els]
|
(for [i 0 len]
|
||||||
(if (>= clen len)
|
(let [el (unsafe-nth els i)]
|
||||||
(break)
|
(if (>= clen len)
|
||||||
(do
|
(break)
|
||||||
(set! consumed (inc consumed))
|
(do
|
||||||
(set! clen (+ 2 (+ clen (length el)))))))
|
(set! consumed (inc consumed))
|
||||||
|
(set! clen (+ 2 (+ clen (length el))))))))
|
||||||
consumed))
|
consumed))
|
||||||
|
|
||||||
|
(hidden decode-arr)
|
||||||
|
(private decode-arr)
|
||||||
(defn decode-arr [s]
|
(defn decode-arr [s]
|
||||||
(if (starts-with? s "*0\r\n")
|
(if (starts-with? s "*0\r\n")
|
||||||
(Success (Null))
|
(Success (Null))
|
||||||
@@ -77,6 +85,7 @@
|
|||||||
(Success (Arr a))
|
(Success (Arr a))
|
||||||
(Error @err)))))))
|
(Error @err)))))))
|
||||||
|
|
||||||
|
(doc from-string "converts a RESP string into a `RESP` data structure.")
|
||||||
(defn from-string [s]
|
(defn from-string [s]
|
||||||
(if (empty? s)
|
(if (empty? s)
|
||||||
(Success (Null))
|
(Success (Null))
|
||||||
@@ -87,9 +96,9 @@
|
|||||||
\$ (decode-bulk-string &(tail s))
|
\$ (decode-bulk-string &(tail s))
|
||||||
\* (decode-arr &(tail s))
|
\* (decode-arr &(tail s))
|
||||||
(Error (fmt "Malformed RESP data: got %s" s)))))
|
(Error (fmt "Malformed RESP data: got %s" s)))))
|
||||||
)
|
|
||||||
|
|
||||||
(definterface to-redis (Fn [a] RESP))
|
(definterface to-redis (Fn [a] RESP))
|
||||||
|
)
|
||||||
|
|
||||||
(defmodule String
|
(defmodule String
|
||||||
(defn to-redis [s] (RESP.Str s))
|
(defn to-redis [s] (RESP.Str s))
|
||||||
@@ -106,22 +115,28 @@
|
|||||||
(defmodule Redis
|
(defmodule Redis
|
||||||
(use-all Array Result Socket)
|
(use-all Array Result Socket)
|
||||||
|
|
||||||
|
(doc open-on "opens the connection to Redis on port `port`.")
|
||||||
(defn open-on [host port]
|
(defn open-on [host port]
|
||||||
(let [s (setup-client host port)]
|
(let [s (setup-client host port)]
|
||||||
(if (valid? &s)
|
(if (valid? &s)
|
||||||
(Success (init s))
|
(Success (init s))
|
||||||
(Error (fmt "Couldn’t connect to %s:%d" host port)))))
|
(Error (fmt "Couldn’t connect to %s:%d" host port)))))
|
||||||
|
|
||||||
|
(doc open "opens the connection to Redis on port 6379.
|
||||||
|
|
||||||
|
For variable port numbers please check out [`open-on`](#open-on).")
|
||||||
(defn open [host] (open-on host 6379))
|
(defn open [host] (open-on host 6379))
|
||||||
|
|
||||||
|
(doc read "reads a `RESP` object from Redis.")
|
||||||
(defn read [r] (RESP.from-string &(Socket.read (sock r))))
|
(defn read [r] (RESP.from-string &(Socket.read (sock r))))
|
||||||
|
(doc send "sends the command `cmd` with the arguments `args` to Redis.")
|
||||||
(defn send [r cmd args]
|
(defn send [r cmd args]
|
||||||
(if (empty? args)
|
(if (empty? args)
|
||||||
(Socket.send (sock r) &(fmt "%s\r\n" &cmd))
|
(Socket.send (sock r) &(fmt "%s\r\n" &cmd))
|
||||||
(Socket.send (sock r) &(str &(RESP.Arr (concat &[[(str &(to-redis cmd))] (copy-map &RESP.str args)]))))))
|
(Socket.send (sock r) &(str &(RESP.Arr (concat &[[(str &(to-redis cmd))] (copy-map &RESP.str args)]))))))
|
||||||
|
|
||||||
|
(doc close "closes the connection to Redis.")
|
||||||
(defn close [r] (Socket.close @(sock &r)))
|
(defn close [r] (Socket.close @(sock &r)))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(defndynamic rtreat- [s]
|
(defndynamic rtreat- [s]
|
||||||
@@ -150,6 +165,8 @@ It takes the same arguments as the [Redis command](https://redis.io/commands/"
|
|||||||
(list 'Redis.send 'r (list 'copy (rtreat- (Symbol.str cmd))) (list 'ref (rconv- args)))
|
(list 'Redis.send 'r (list 'copy (rtreat- (Symbol.str cmd))) (list 'ref (rconv- args)))
|
||||||
'(Redis.read r)))))
|
'(Redis.read r)))))
|
||||||
|
|
||||||
|
; these commands were scraped from redis.io on the 9th of Feb 2020
|
||||||
|
|
||||||
(defredis append key value)
|
(defredis append key value)
|
||||||
(defredis auth password)
|
(defredis auth password)
|
||||||
(defredis bgrewriteaof)
|
(defredis bgrewriteaof)
|
||||||
@@ -391,3 +408,16 @@ It takes the same arguments as the [Redis command](https://redis.io/commands/"
|
|||||||
(defredis latency-latest)
|
(defredis latency-latest)
|
||||||
(defredis latency-reset)
|
(defredis latency-reset)
|
||||||
(defredis latency-help)
|
(defredis latency-help)
|
||||||
|
(doc Redis "is a wrapper around Redis connections. It supports opening a
|
||||||
|
connection using [`open`](#open) or [`open-on`](#open-on), reading from and
|
||||||
|
sending to the connection (using [`read`](#read) and [`send`](#send),
|
||||||
|
respectively), and contains thin wrappers around all Redis commands (everything
|
||||||
|
else).")
|
||||||
|
(doc RESP "is a wrapper around the [Redis Serialization
|
||||||
|
Protocol](https://redis.io/topics/protocol). You can create all types—though
|
||||||
|
creating arrays is a little unsightly due to the absence of recursive types—,
|
||||||
|
stringify the built types into strings using [`str`](#str), and decoding from
|
||||||
|
the string protocol using [`from-string`](#from-string).
|
||||||
|
|
||||||
|
If you want your types to be supported when encoding, you’ll have to implement
|
||||||
|
the interface `to-redis`, the signature of which is `(Fn [a] RESP))`.")
|
||||||
|
Reference in New Issue
Block a user