[−][src]Crate msgpack_simple
Simplified, easy to use, pure Rust MessagePack implementation focused on handling dynamic data structures.
Example usage:
use msgpack_simple::{MsgPack, MapElement, Extension}; let message = MsgPack::Map(vec![ MapElement { key: MsgPack::String(String::from("hello")), value: MsgPack::Int(42) }, MapElement { key: MsgPack::String(String::from("world")), value: MsgPack::Array(vec![ MsgPack::Boolean(true), MsgPack::Nil, MsgPack::Binary(vec![0x42, 0xff]), MsgPack::Extension(Extension { type_id: 2, value: vec![0x32, 0x4a, 0x67, 0x11] }) ]) } ]); let encoded = message.encode(); // encoded is a Vec<u8> let decoded = MsgPack::parse(&encoded).unwrap(); println!("{}", decoded); assert_eq!(message, decoded); assert!(message.is_map()); let mut map = message.as_map().unwrap(); // map is a Vec<MapElement> let second_element = map.remove(1); assert!(second_element.key.is_string()); assert_eq!(second_element.key.as_string().unwrap(), "world".to_string()); assert!(second_element.value.is_array()); let mut array = second_element.value.as_array().unwrap(); // array is a Vec<MsgPack> let nil = array.remove(1); assert!(nil.is_nil());
Data is abstracted with the MsgPack enum, which can contain any kind of data encodable with MessagePack. This is designed for dynamic data, for static models, mneumann's rust-msgpack or 3Hren's RMP crates are recommended.
Decoding MsgPack
msgpack_simple provides two functions for decoding data. For general use,
MsgPack::parse()
is recommended:
use msgpack_simple::MsgPack; let data = vec![0xaa, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x52, 0x75, 0x73, 0x74]; let decoded = MsgPack::parse(&data); assert!(decoded.is_ok()); let decoded = decoded.unwrap(); assert!(decoded.is_string()); assert_eq!(decoded.as_string().unwrap(), "Hello Rust".to_string());
MsgPack::parse()
takes a byte array slice (&[u8]
) and returns an
MsgPack enum wrapped in a result. The error type is
ParseError, which can show the byte where the
parser encountered an error if needed.
If you need more control, you can use the parser
module directly:
use msgpack_simple::parser; let data = vec![0xaa, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x52, 0x75, 0x73, 0x74, 0x00]; let (decoded, length) = parser::parse(&data).unwrap(); assert!(decoded.is_string()); assert_eq!(decoded.as_string().unwrap(), "Hello Rust".to_string()); assert_eq!(length, 11);
parser::parse()
behaves identically, but it also returns the length of the
MessagePack data parsed.
Encoding MsgPack
msgpack_simple provides the MsgPack.encode()
function for encoding data:
use msgpack_simple::MsgPack; let message = MsgPack::String("Hello Rust".to_string()); let encoded = message.encode(); let data = vec![0xaa, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x52, 0x75, 0x73, 0x74]; assert_eq!(encoded, data);
Accessing MsgPack
For every variant of the enum (String, Float, Array, etc.) MsgPack provides
two convenience functions, one of which checks the data against the type
(is_string()
, is_float()
, is_array(
), etc.), and the other one
transforms the MsgPack enum into the value it contains (as_string()
,
as_float()
, as_array()
, etc.).
use msgpack_simple::MsgPack; let message = MsgPack::String("Hello Rust".to_string()); assert_eq!(message.is_float(), false); assert_eq!(message.is_string(), true); let float = message.clone().as_float(); // the as_type functions consume the MsgPack let string = message.as_string(); assert!(float.is_err()); assert!(string.is_ok());
There are two special cases: as_nil()
does not exist because the Nil
variant holds no data, and there is an is_some_int()
and as_some_int()
pair, which matches both Int and Uint and returns i64
.
Arrays, Maps, and Extensions
One of MessagePack's greatest strengths is a compact representation of dynamic, nested hierarchies. To access that, msgpack_simple provides simple Rust abstractions for these types:
- Array is represented with
Vec<MsgPack>
- Map is represented with
Vec<MapElement>
- Extension is represented with
Extension
MapElement and Extension
are two custom structs with simple representations of their respective
types. MapElement simply has a key
and a value
, both with the MsgPack
type, and Extension has a type_id
(i8
) and a value
(Vec<u8>
).
use msgpack_simple::{MsgPack, MapElement, Extension}; let message = MsgPack::Array(vec![ MsgPack::Map(vec![ MapElement { key: MsgPack::String("foo".to_string()), value: MsgPack::Int(42) }, MapElement { key: MsgPack::Extension(Extension { type_id: 27, value: vec![0x32] }), value: MsgPack::Binary(vec![0x2a, 0xf4]) } ]) ]); let mut array = message.as_array().unwrap(); let mut map = array.remove(0).as_map().unwrap(); let first = map.remove(0); let second = map.remove(0); assert_eq!(first.value.as_some_int().unwrap(), 42); assert_eq!(second.key.as_extension().unwrap().type_id, 27);
Modules
parser | The actual parser under the hood |
Structs
ConversionError | An error that occurred when trying to access a field as a different type |
Extension | Represents an extension field |
MapElement | Represents an element in a MessagePack map |
ParseError | An error that occurred while parsing a binary as MsgPack |
Enums
MsgPack | A piece of MessagePack-compatible data |