4 releases (2 breaking)
0.4.0 | Mar 26, 2022 |
---|---|
0.2.1 | Dec 28, 2021 |
0.2.0 | Feb 8, 2021 |
0.1.0 | Dec 22, 2020 |
#2172 in Encoding
Used in 2 crates
41KB
807 lines
Rust bindings for the nachricht data interchange format
This is a pure Rust implementation of the binary nachricht data interchange format.
Minimum supported Rust version
Since this crates makes use of the fallible collection API to pre-allocate Collections when deserializing values, the
minimum required Rust version is 1.57.0
.
Usage
Add this to your Cargo.toml:
[dependencies]
nachricht = "0.4.0"
Then you can construct, encode and decode nachricht messages:
use std::borrow::Cow;
use std::collections::BTreeMap;
use nachricht::*;
fn main() -> Result<(), Box<dyn Error>> {
let mut buf = Vec::new();
let nachricht = Value::Record(BTreeMap::from([(Cow::Borrowed("key"), Value::Str(Cow::Borrowed("value")))]));
Encoder::encode(&nachricht, &mut buf)?;
let decoded = Decoder::decode(&buf)?.0;
assert_eq!(nachricht, decoded);
Ok(())
}
lib.rs
:
All encoding functions take &self
and a writer and return the amount of written bytes. All decoding functions take
a buffer and return Self
and the number of consumed bytes.
A note on usize
nachricht
internally uses 64 bit unsigned integers to signify field lengths. Rust however uses the
architecture-dependent usize
for slice indexing. This means that on architectures where usize
is smaller than
u64
(32 bit i386 for instance), some valid nachricht
messages can not be decoded since there would be no way to
efficiently index the containers. A DecodeError::Length
will be raised in these instances. Likewise, on
architectures where usize
is larger than u64
, some valid Rust datastructures can not be encoded since there is
no way to represent them in the wire format. A EncodeError::Length
will be raised in these instances.
A note on Maps
The variant Value::Map
uses a Vec
of key-value pairs internally because Rust's floating point types f32
and
f64
implement neither Ord
nor Hash
and thus a nachricht Value
cannot be used as a key in any of the standard
library maps.
Likewise, Value::Record
uses a BTreeMap
instead of a HashMap
because field names need to have a stable
ordering when deciding if a record with the same layout has already been encoded so that it can be reused.
Examples
use nachricht::*;
use std::borrow::Cow;
use std::collections::BTreeMap;
let mut buf = Vec::new();
let value = Value::Record(BTreeMap::from([(Cow::Borrowed("key"), Value::Str(Cow::Borrowed("value")))]));
Encoder::encode(&value, &mut buf);
assert_eq!(buf, [
0xa1, // Record of length 1
0x63, // Symbol of length 3
0x6b, // 'k'
0x65, // 'e'
0x79, // 'y'
0x45, // Str of length 5
0x76, // 'v'
0x61, // 'a'
0x6c, // 'l'
0x75, // 'u',
0x65, // 'e'
]);
let decoded = Decoder::decode(&buf).unwrap();
assert_eq!(value, decoded.0);
assert_eq!(11, decoded.1);