RESP parser and validator

Since v1.0.0, the crate is published as io_resp and no more ~~squall_dot_io_resp~~.

A RESP (REdis Serialization Protocol) parser implementation, written with edge performance in mind.

If you are not familiar with RESP, consider starting here with [RESP specs]. RESP is a binary safe serialization protocol. Initially developed for the ReDiS project, it is injection safe (needs no escaping) and is fast-forward as it requires no look-back in parsing.

This crate aims to parse and validate your RESP strings. Since the protocol can be used beyond its initial scope, to a general-purpose communication scheme.

To do so, its reuses Rust TryInto trait to try and parse your &str as a valid RESP. Implemented on a Value enum of RESP tokens, it returns a Rust Result<Value, Error>.

Usage

Add dependency to your project: editorconfig ; Cargo.toml [dependecies] io_resp = "0.1.2"

Here are example with code: ```rust use ioresp::{ Node::{self, NIL, SIZE, ARRAY, ERROR, INTEGER, UNKNOWN, SIMPLESTRING, BULK_STRING}, Value::{self, Nil, Error, Array, String, Integer}, Error as VError, ValueResult, };

asserteq!( // Empty RESP "".tryinto() as ValueResult, Err(VError::Unexpected {node: UNKNOWN, index: 0}));

asserteq!( // Unterminated number: missing "\r\n" ":0".tryinto() as ValueResult, Err(VError::Unexpected {node: INTEGER, index: 2}));

asserteq!( // Not enough elements in the array "*2\r\n$-1\r\n".tryinto() as ValueResult, Err(VError::Size {node: ARRAY, index: 9}));

asserteq!( // Longer bulk string: got more that 2-bytes "$2\r\nHello\r\n".tryinto() as ValueResult, Err(VError::Size {node: BULK_STRING, index: 6}));

asserteq!( // Sorter bulk string: shorter by 1-byte (capital A acute is 2-bytes) "$3\r\nÂ\r\n".tryinto() as ValueResult, Err(VError::Size {node: BULK_STRING, index: 7})); ```

```rust use ioresp::{ Node::{self, NIL, SIZE, ARRAY, ERROR, INTEGER, UNKNOWN, SIMPLESTRING, BULKSTRING}, Value::{self, Nil, Error, Array, String, Integer}, Error as VError, ValueResult, }; // JSON: null asserteq!( Value::try_from("$-1\r\n"), Ok(Nil) );

// JSON: 10 asserteq!( Value::tryfrom(":10\r\n"), Ok(Integer(10)) );

// JSON: "Nina Simone" asserteq!( Value::tryfrom("+Nina Simone\r\n"), Ok(String("Nina Simone".into())) );

// JSON: "Lorem ipsum...\r\nDolor sit amet..." asserteq!( Value::tryfrom("$33\r\nLorem ipsum...\r\nDolor sit amet...\r\n"), Ok(String("Lorem ipsum...\r\nDolor sit amet...".into())) );

// JavaScript: [null, 447, new Error("Oh oh!"), "Hourly", "Si vis pacem,\r\npara bellum"] asserteq!( Value::tryfrom("*5\r\n$-1\r\n:447\r\n-Oh oh!\r\n+Hourly\r\n$26\r\nSi vis pacem,\r\npara bellum\r\n"), Ok(Array(vec![ Nil, Integer(447), Error("Oh oh!".into()), String("Hourly".into()), String("Si vis pacem,\r\npara bellum".into()) ])) );

// NOTE: Even recursive arrays - we leave that for you to try out. ```

License

MIT

Contributions

Should you find some [issues], please report on GitHub project, or consider opening a [pull-request].