Resend
Resend is a easy to use, performant, customizable and extendable Rust library for little-endian/big-endian serializing and deserializing.
Example
Two functions only:
snd() for any Write implementors (File, TcpStream etc)
rcv() for any Read implementors (File, TcpStream etc)
Cargo.toml:
[]
#with little-endian feature
= { = "0.1", = ["little"]}
Code:
use ;
let mut vec = Vec new;
vec.snd?;
vec.snd?;
vec.snd?;
vec.snd?;
let mut buf = &vec;
let v: i8 = buf.rcv?;
let v: u16 = buf.rcv?;
let v: u32 = buf.rcv?;
let v: String = buf.rcv?;
Derive
[]
= { = "0.1", = ["little"]}
= "0.1"
use ;
use ;
...
let dt: DeviceType = stream.rcv?;
stream.snd?;
Performant
Write/Read trait based, no intermediate variables.
Format
- bool is serialized as 0_u8 (false) or 1_u8 (true).
- String, Vec, Array, Slice, Collections, Ascii, UTF16: u32_length_header + data, no lengh header if "len" attribute is used.
- Option is serialized as bool_header + optional data, no bool_header if "when" attribute is used.
- Enum is serialized as tag value(int) + optional data. Use "repr" attribute for the size of tag value.
Color::Red is serialized as 0_u16. Color::Blue is serialized as 32_u16.
DeviceType::PrinterType(printer) is serialized as 4_u32 + IoPrinter data. DeviceType::ScardType is serialized as 0x20_u32.
Please be aware: discriminants on non-unit variants are experimental for now (Rust 1.65), you have to use Rust nightly for this.
Customizable (attributes)
- Send both little-endian and big-endian at the same time with the resend::endian::little::LE and resend::endian::big::BE:
stream.snd?;
-
No serialization with #[skip] attribute.
-
The length of String, Vector etc. can be from another field or constant with #[len(field_name_or_const)] attribute:
- #[when(expr)] attribute is used on Option field. This field will be deserialized only if the expr is true. Warning: "expr" is not checked on serializing, no extra bool value in this case.
- Length can be u16 or VLQ with features (u32 by default)
= { = "0.1", = ["little", "len_16"]}
= { = "0.1", = ["big", "len_vlq"]}
- Restricted length with features: MAX_LEN_100M, MAX_LEN_500M, MAX_LEN_2G
= { = "0.1", = ["little", "len_16", "MAX_LEN_100M"]}
Extendable
For example, you want a string with variable-length quantity
;
Resend includes the following types for your convenience:
use ;
Implements resend::FromReader and resend::IntoWriter if you need the "len(field_name)" attribute working on your type. For example:
Tips
-
String, Ascii and UTF16 with #[len(field_name_or_const)] attribute: if the specified length is bigger then the actual length: extra '\0' will be appended when it's serialized, and extra '\0' will be removed after it's deserialized; if the specified length is smaller, the string will be truncated to that length. This is useful if you need null terminated, fixed length string.
-
Convert int to Enum
//Conver little-endian u16 to Blue ("little" feature)
//[u8] doesn't implement Read, convert it to &[u8] with as_ref()
let c: Color = .as_ref.rcv?;
- Use enumeration to serialize Object Oriented classes:
//type value (enum tag value) after the parent class
//type value (enum tag value) before the parent class
enum
- resend::endian:Length handles 3 types: u32, u16, VLQ. It's better to use this Length type directly in your object.
License
MIT OR Apache-2.0
Credits
This library is developed for Remote Spark Corp's RDP (Remote Desktop Protocol) Project.