#serde #serialization #klv

serde_klv

KLV data format for Serde

5 unstable releases

0.3.0 Jan 16, 2023
0.2.1 Jan 4, 2023
0.2.0 Jan 2, 2023
0.1.1 Dec 26, 2022
0.1.0 Dec 13, 2022

#814 in Encoding

Download history 8/week @ 2024-02-22 4/week @ 2024-02-29 105/week @ 2024-03-07 35/week @ 2024-03-14 4/week @ 2024-03-28

144 downloads per month

MIT/Apache

76KB
2K SLoC

Serde KLV   Build Status Latest Version Rustc Version 1.65+

Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.


You may be looking for:

Usage

use serde_klv::{from_bytes, to_bytes};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, PartialEq)]
// Set Universal Key string or byte-literal
#[serde(rename = "TESTDATA00000000")]
// #[serde(rename = "\x06\x0e\x2b\x34\x02\x0b\x01\x01\x0e\x01\x03\x01\x01\x00\x00\x00")]
struct TestStruct<'a> {
    // rename to u8 range number
    #[serde(rename = "10")]
    u8: u8,
    #[serde(rename = "11")]
    u64: u64,
    // can use Option
    #[serde(rename = "120", skip_serializing_if = "Option::is_none")]
    none_skip_some: Option<u16>,
    #[serde(rename = "121", skip_serializing_if = "Option::is_none")]
    none_skip_none: Option<u16>,
    #[serde(rename = "60")]
    str: &'a str,
    // Use `serde_bytes` when using Vec<u8} or &[u8]: https://crates.io/crates/serde_bytes
    #[serde(rename = "61", with = "serde_bytes")]
    bytes: &'a [u8],
    // Implement a serializer when using structs
    #[serde(rename = "62", with = "timestamp_micro")]
    ts: SystemTime,
}

mod timestamp_micro {
    use serde::{Deserialize, Deserializer, Serializer};
    use std::time::{Duration, SystemTime};

    pub fn serialize<S>(date: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let micros = date
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_micros();
        serializer.serialize_u64(micros as u64)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<SystemTime, D::Error>
    where
        D: Deserializer<'de>,
    {
        let micros = u64::deserialize(deserializer)?;
        SystemTime::UNIX_EPOCH
            .checked_add(Duration::from_micros(micros))
            .ok_or_else(|| serde::de::Error::custom("failed to deserialize systemtime"))
    }
}

fn main() {
    let ts = SystemTime::UNIX_EPOCH
            .checked_add(Duration::from_micros(1_000_233_000))
            .unwrap();
    let t = TestStruct {
        u8: 127,
        u64: u32::MAX as u64 + 1,
        none_skip_some: Some(2016),
        none_skip_none: None,
        str: "this is string",
        bytes: b"this is byte",
        ts,
    };
    let buf = to_bytes(&t).unwrap();
    let x = from_bytes::<TestStruct>(&buf).unwrap();
    assert_eq!(&t, &x);

    // with checksum
    use serde_klv::{from_bytes_with_checksum, to_bytes_with_checksum, WrappedCRC};
    
    let buf = to_bytes_with_checksum(&t, WrappedCRC::default()).unwrap();
    let x: TestStruct = from_bytes_with_checksum(&buf, WrappedCRC::default()).unwrap();
    assert_eq!(&t, &x);
}

Dependencies

~295–570KB
~12K SLoC