[−][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 |