# MessagePacker - a no-std msgpack implementation
[](https://crates.io/crates/msgpacker)
[](https://docs.rs/msgpacker/)
[]()
The protocol specification can be found [here](https://github.com/msgpack/msgpack/blob/master/spec.md).
This crate targets simplicity and performance. No dependencies are used, just the standard Rust library.
It will implement `Packable` and `Unpackable` for Rust atomic types. The traits can also be implemented manually.
## Features
- alloc: Implements the functionality for `Vec`, `String`, and unlocks custom extensions.
- derive: Enables `MsgPacker` derive convenience macro.
- strict: Will panic if there is a protocol violation of the size of a buffer; the maximum allowed size is `u32::MAX`.
- std: Will implement the `Packable` and `Unpackable` for `std` collections.
- serde: Adds support for [serde](https://crates.io/crates/serde)
## Known issues
- The library, as noted in issue [#18](https://github.com/codx-dev/msgpacker/issues/18), exhibits a stricter approach when importing data generated by external tools due to the support of mixed types in languages like Python for collections. A pertinent instance from that issue involves an array serialization where the initial element is a u64, followed by a f64. While a solution can be devised in Rust using a wrapper that abstracts primitive types, it introduces an undesirable overhead that may not be suitable for typical use cases. Although this feature could potentially be added in future updates, it remains unimplemented at present.
## Example
```rust
use msgpacker::prelude::*;
use std::collections::HashMap;
// boilerplate derives - those aren't required
#[derive(Debug, PartialEq, Eq)]
// this convenience derive macro will implement `Packable` and `Unpackable`
#[derive(MsgPacker)]
pub struct City {
name: String,
// The traits are implemented for stdlib collections. If you have a custom map, you can use the
// directive `#[msgpacker(map)]` so the traits will be automatically implemented through the
// iterators of the map.
inhabitants_per_street: HashMap<String, u64>,
// This is also automatically implemented. The manual implementation is via `#[msgpacker(array)]`.
zones: Vec<String>,
}
// create an instance of a city.
let city = City {
name: "Kuala Lumpur".to_string(),
inhabitants_per_street: HashMap::from([
("Street 1".to_string(), 10),
("Street 2".to_string(), 20),
]),
zones: vec!["Zone 1".to_string(), "Zone 2".to_string()],
};
// serialize the city into bytes
let mut buf = Vec::new();
let n = city.pack(&mut buf);
println!("serialized {} bytes", n);
// deserialize the city and assert correctness
let (n, deserialized) = City::unpack(&buf).unwrap();
println!("deserialized {} bytes", n);
assert_eq!(city, deserialized);
```
## Serde
Version `0.5.0` introduces [serde](https://crates.io/crates/serde) support.
```rust
use msgpacker::serde;
use serde_json::{json, Value};
let val = serde_json::json!({"foo": "bar"});
let ser = serde::to_vec(&val);
let des: Value = serde::from_slice(&ser).unwrap();
assert_eq!(val, des);
```
While it's important to recognize that `serde`'s performance can be notably slower, this is primarily due to its implementation of a visitor pattern for type serialization, rather than solely relying on the static structure of declarations. However, `serde` is broadly used and having its support is helpful since a plethora of other libraries will be automatically supported just by having this feature enabled.
For more information, refer to `Benchmarks`.
## Benchmarks
Results obtained with `AMD EPYC 7402P 24-Core Processor`.






To run the benchmarks:
```sh
cd msgpacker-bench && cargo bench
```