Expand description
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§
- Conversion
Error - 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
- Parse
Error - An error that occurred while parsing a binary as MsgPack
Enums§
- MsgPack
- A piece of MessagePack-compatible data