Skip to content
/ jbytes Public
forked from caizhengxin/jbytes

This is a byte stream structured serialization and deserialization library.

License

Notifications You must be signed in to change notification settings

zelozzz/jbytes

This branch is 10 commits behind caizhengxin/jbytes:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

7a26d61 · Jan 9, 2025

History

69 Commits
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 9, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 8, 2025
Jan 9, 2025
Jan 9, 2025

Repository files navigation

jbytes

Crates.io Crates.io License

This is a Rust-based implementation of byte stream structured serialization/deserialization general library, can be applied to network packet parsing, network packet group package, network communication, file content parsing, etc., feel good small partners please click like 👍~

Install

Cargo.toml

[dependencies]
jbytes = { version="0.2.0", features = ["derive"] }

no_std:

[dependencies]
jbytes = { version="0.2.0", default-features = false, features = ["derive"] } # default use alloc.

Example

Bytes Example

use jbytes::prelude::*;


fn main() {
    let bytes = Bytes::new(b"\x01\x02\x03");
    assert_eq!(bytes.take_be_u16(), Ok(0x0102));
    assert_eq!(bytes.take_be_u16().is_err(), true);
}

Buffer Example

use jbytes::prelude::*;


fn buffer_example(buffer: &mut Buffer) -> JResult<()>  {
    buffer.push_be_u16(1)?;
    buffer.push(b"\x01\x02\x03")?;

    Ok(())
}


fn main() {
    let mut buffer = Buffer::new();
    if buffer_example(&mut buffer).is_ok() {
        assert_eq!(*buffer, b"\x00\x01\x01\x02\x03");
    }
}

Simple Example

use jbytes::{ByteEncode, ByteDecode};
use jbytes::prelude::*;


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub struct SimpleExample {
    pub length: u16,
    #[jbytes(length="length")]
    pub value: String,
    pub cmd: u8,
    #[jbytes(branch="cmd")]
    pub body: SimpleExampleBody,
}


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub enum SimpleExampleBody {
    #[jbytes(branch_value=1)]  // Set 1
    Read {
        address: u8,
    },
    Write {
        address: u8,
        value: [u8; 3],
    },                        // Increment to 2
    #[jbytes(branch_default)]
    Unknown,                  // _ => { ... }
}


fn main() -> JResult<()> {
    let input = b"\x00\x03\x31\x32\x33\x01\x05";
    let value: SimpleExample = jbytes::decode(input)?;
    assert_eq!(value, SimpleExample { length: 3, value: "123".to_string(), cmd: 1, body: SimpleExampleBody::Read { address: 5 } });
    assert_eq!(*jbytes::encode(value)?, input);
}

default value example

[dependencies]
jbytes = { version="0.2.0", features = ["derive", "jdefault"] }
use jbytes::{ByteEncode, ByteDecode, Jdefault};
use jbytes::prelude::*;


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
pub struct SimpleExample {
    #[jbytes(byte_count=1, default="\"123\".to_string()")]
    pub value: String,
    #[jbytes(byte_count=1)]
    pub body: SimpleExampleBody,
}


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
pub enum SimpleExampleBody {
    #[jbytes(branch_value=1)]
    Read {
        address: u8,
    },
    Write {
        address: u8,
        value: [u8; 3],
    },
    #[jbytes(branch_default)]
    Unknown {
        #[jbytes(default=10)]
        value: u8,
    },
}


fn main() -> JResult<()> {
    let value = SimpleExample::default();
    assert_eq!(value, SimpleExample {
        value: "123".to_string(),
        body: SimpleExampleBody::Unknown { value: 10 },
    });

    assert_eq!(*jbytes::encode(value)?, b"\x03\x31\x32\x33\x03\x0a");

    let value: SimpleExample = jbytes::decode(b"\x03\x31\x32\x33\x03\x0a")?;
    assert_eq!(value, SimpleExample {
        value: "123".to_string(),
        body: SimpleExampleBody::Unknown { value: 10 },
    });
}

Other example

DataType

  • u8/u16/u32/u64/usize/u128
  • i8/i16/i32/i64/isize/i128
  • bool
  • char
  • f32/f64
  • String
  • &str
  • &[u8]
  • array[T; N]
  • tuple
  • Vec<T>
  • Option<T>
  • Struct
  • Enum
  • PhantomData
  • HashMap
  • HashSet
  • MacAddress
  • std::net::Ipv4Addr
  • std::net::Ipv6Addr
  • std::net::IpAddr
  • NetAddress
  • HexString
  • DateTime
  • Bit

Macro modifier attribute

ContainerAttrModifiers

It is used to modify the global definition of a struct/enum, indicating that all the fields in struct/enum follow. You can also use 'FieldAttrModifiers' to modify a single content.

Universal modifier

  • byteorder=<"BE"|"LE"|variable(BE=0,LE=1)>: Specifies byte order, BE(big-endian)/LE(little-endian), eg: byteorder example.
  • encode_with=<func>: Specifies custom encode function, eg: encode_with example.
  • decode_with=<func>: Specifies custom decode function, eg: decode_with example.
  • with=<mod>: Specifies custom encode/decode function, eg: with example.
  • get_variable_name=<variable>: Get cache variable, must be used with 'variable_name', can be used for different struct or enum type passing, eg: variable_name_example.

Enum type modifier

  • byte_count_disable: Disable the default reading of 1 byte to implement the match enumeration branch.
  • branch_enum

FieldAttrModifiers

It is used to modify a field in the struct/enum.

  • byteorder=<"BE"|"LE"|variable(BE=0,LE=1)>: Specifies byte order, BE(big-endian)/LE(little-endian), eg: byteorder example.
  • length=<num|variable>: Specifies read data length, Support int/&str/String/&[u8]/Vec/.. Type, eg: length example.
  • offset=<num|variable>: Specifies n positions forward from the current position to offset the data flow, eg: offset example.
  • full=<int>: Specifies the encode encoding fill value, which defaults to 0 and is often used to fill the encode encoding after the offset, eg: full example.
  • byte_count=<1..8>: Specifies the number of bytes to be converted into an integer, representing the byte stream length to be read later, eg: byte_count example.
  • remaining: Takes all remaining bytes, eg: remaining example.
  • untake: Specifies the data read position does not move, and data can continue to be read from this position, eg: untake example.
  • encode_value=<expr>: Specifies the value handler expression for encode function, eg: encode_value example.
  • decode_value=<expr>: Specifies the value handler expression for decode function, eg: decode_value example.
  • variable_name=<variable>: Specifies the integer type cache variable and uses it in other Struct/Enum via the get_variable_name modifier, eg: variable_name example.
  • skip: Skip the 'encode/decode' function for this field, the type needs to implement the 'Default' trait, eg: skip example.
  • skip_encode: Skip the encode function for this field, eg: skip_encode example.
  • skip_decode: Skip the 'decode' function for this field, the type needs to implement the 'Default' trait, eg: skip_decode example.
  • if_expr=<bool expr>: Specifies if condition expression, Support Option<T> Type, eg: if_expr example.
  • encode_with=<func>: Specifies custom encode function, eg: encode_with example.
  • decode_with=<func>: Specifies custom decode function, eg: decode_with example.
  • with=<mod>: Specifies custom encode/decode function, eg: with example.
  • with_args=<variable>: Specifies custom encode/decode function parameter, eg: with_args example.
  • linend|end_with=<string|bytes>: Specifies end position, Support String/&str/&[u8]/HashMap/.. Type, eg: linend.
  • key|starts_with: Specifies the exact matching keyword, Support string/&str/&[u8]/.. Type, eg: key example.
  • split: Specifies the delimiter, often used for things like 'Key: Value', and supports the HashMap type, eg: split example
  • from_str: Specifies that the conversion is done by the FromStr type, eg: from_str example.
  • from_str=<type>: Specifies that the conversion is done by the Type::FromStr type, eg: from_str example.
  • check_value: Check whether the result is normal. If an exception occurs, an error is returned, eg: check_value example.

Container type modifier, eg: Vec/HashMap/HashSet etc.

  • count=<num|variable>: Specifies the number of container elements, Support Vec/HashMap/HashSet type, eg: count example.
  • try_count=<num|variable>: Specifies max the number of container elements, if insufficient, no parsing error is returned, Support Vec/HashMap/HashSet Type, eg: try_count example.
  • byte_count_outside=<1..8>: Specifies the number of container elements, Similar byte_count, SupportVec/HashMap/HashSet/.. type, eg: byte_count_outside example.

enum branch modifier

  • branch: Specifies the enumeration (Enum) type branching condition, eg: branch example.
  • branch_value: Specifies an enumeration (Enum) type branch matching condition, eg: branch_value example.
  • branch_range: Specifies an enumeration (Enum) type branch matching range, eg: branch_range example.
  • branch_bits: Specifies an enumeration (Enum) type branch matching condition, eg: branch_bits example.
  • branch_default: Specifies an enumeration (Enum) type default condition, eg: branch_default example.

About

This is a byte stream structured serialization and deserialization library.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%