RESP

is a wrapper around the Redis Serialization Protocol. You can create all types, stringify the built types into strings using str, decode single values with from-string, and decode multiple concatenated values with decode-n. Arrays are fully supported, including nested arrays.

; decoding
(RESP.from-string "+OK\r\n")       ; => (Success (Str @"OK"))
(RESP.from-string ":42\r\n")       ; => (Success (Integer 42))
(RESP.from-string "$-1\r\n")       ; => (Success (Null))

; encoding
(str &(RESP.Str @"hi"))             ; => "$2\r\nhi\r\n"
(str &(RESP.Integer 42))            ; => ":42\r\n"

; pattern matching on responses
(match (Redis.get &r @"key")
  (Result.Success resp)
    (match resp
      (RESP.Str s) (println* "got: " &s)
      (RESP.Null) (println* "not found")
      (RESP.Arr items) (println* "array of " &(Int.str (Array.length &items)))
      _ (println* "other"))
  (Result.Error e) (println* "error: " &e))

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)).

Arr

instantiate

(Fn [(Array (Box RESP))] RESP)

creates a Arr.

Err

instantiate

(Fn [String] RESP)

creates a Err.

Integer

instantiate

(Fn [Int] RESP)

creates a Integer.

Null

instantiate

(Fn [] RESP)

creates a Null.

Str

instantiate

(Fn [String] RESP)

creates a Str.

bulk-fill-target

defn

(Fn [(Ref String a), Int, Int] (Maybe Int))

                        (bulk-fill-target s start slen)
                    

the buffer length the partial bulk string at start needs before it decodes, when its header has arrived but its payload has not; else Nothing.

copy

instantiate

(Fn [(Ref RESP a)] RESP)

copies a RESP.

decode-available

defn

(Fn [(Ref String a), Int, Int] (Pair (Array RESP) Int))

                        (decode-available s start n)
                    

decodes up to n complete RESP values from s, starting at byte offset start.

Returns a Pair of the decoded values and the byte offset just past the last one — where a streaming caller should resume once more bytes arrive. Decoding stops at the first incomplete or malformed value, so the array may hold fewer than n values and the offset then marks the start of the still-unconsumed tail. Unlike decode-first it consumes many values in a single left-to-right pass without re-slicing between them, which is what lets a buffered reader stay linear instead of quadratic.

decode-first

defn

(Fn [(Ref String a)] (Result (Pair RESP String) String))

                        (decode-first s)
                    

decodes the first complete RESP value from s.

Returns that value paired with the remaining, still-unconsumed suffix of s. Unlike decode-n, it reports the leftover bytes, so a caller streaming from a socket can keep a partial trailing value — or a whole value that coalesced into the same read — buffered until it is needed. Returns an Error if s does not begin with a complete RESP value, either because the input is malformed or because a value is truncated mid-way.

decode-n

defn

(Fn [(Ref String a), Int] (Array RESP))

                        (decode-n s n)
                    

decodes up to n RESP values from string s.

Returns an array of the values that could be successfully decoded. If the array has fewer than n elements, the string did not contain enough complete RESP data.

delete

instantiate

(Fn [RESP] ())

deletes a RESP. This should usually not be called manually.

encode-command

defn

(Fn [(Ref String a), (Ref (Array RESP) b)] String)

                        (encode-command cmd args)
                    

encodes command name cmd and its already-encoded args into a RESP multi-bulk wire string. Sub-commands in cmd are separated by spaces (e.g. @"CLIENT ID").

fatal-error-at

defn

(Fn [(Ref String a), Int, Int] (Maybe String))

                        (fatal-error-at s start slen)
                    

the decoder error for the value at start in s, if no amount of further input could ever make it decode; else Nothing.

from-string

defn

(Fn [(Ref String a)] (Result RESP String))

                        (from-string s)
                    

converts a RESP string into a RESP data structure.

Arrays nested deeper than max-depth are rejected as malformed.

get-tag

instantiate

(Fn [(Ref RESP a)] Int)

Gets the tag from a RESP.

max-depth

def

Int

the deepest array nesting the decoders accept; deeper input is rejected as malformed.

prn

instantiate

(Fn [(Ref RESP a)] String)

converts a RESP to a string.

str

defn

(Fn [(Ref RESP a)] String)

                        (str r)
                    

converts a RESP to a string.