12 releases (2 stable)
1.1.0 | Aug 13, 2024 |
---|---|
1.0.0 | Apr 4, 2024 |
0.10.0 | Apr 1, 2024 |
0.9.0 | Mar 29, 2024 |
#85 in #byte-stream
Used in 3 crates
(via jppe)
72KB
1K
SLoC
jppe-rs
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
$ rustup install nightly
$ cargo +nightly build release
Usage
Cargo.toml
[dependencies]
jppe = { version="1.1.0", features = ["derive"] }
Or
[dependencies]
jppe = { version="1.1.0", features = ["derive", "serde"] }
no_std:
[dependencies]
jppe = { version="1.1.0", default-features = false, features = ["derive"] } # default use alloc.
Simple Example
use jppe::{ByteEncode, ByteDecode};
// If the value size is less than 0xff, byte_count does not need to be specified,otherwise, byte_count=<2|4|8>
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub struct SimpleExample {
pub version: u8,
// #[jppe(byte_count=1)]
pub value: String,
// #[jppe(byte_count=1)]
pub body: SimpleExampleBody,
}
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
#[repr(u8)]
pub enum SimpleExampleBody {
Read {
address: u8,
} = 1,
Write {
address: u8,
value: [u8; 3],
},
#[jppe(enum_default)]
Unknown,
}
fn main() {
let input = b"\x01\x03\x31\x32\x33\x01\x05";
let (input_remain, value) = jppe::decode::<SimpleExample>(input).unwrap();
assert_eq!(value, SimpleExample { version: 1, value: "123".to_string(), body: SimpleExampleBody::Read { address: 5 } });
assert_eq!(input_remain.is_empty(), true);
assert_eq!(jppe::encode(value), input);
}
Simple Example2
use jppe::{ByteEncode, ByteDecode};
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub struct SimpleExample {
pub length: u16,
#[jppe(length="length")]
pub value: String,
pub cmd: u8,
#[jppe(branch="cmd")]
pub body: SimpleExampleBody,
}
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
#[repr(u8)]
pub enum SimpleExampleBody {
Read {
address: u8,
} = 1,
Write {
address: u8,
value: [u8; 3],
},
#[jppe(enum_default)]
Unknown,
}
fn main() {
let input = b"\x00\x03\x31\x32\x33\x01\x05";
let (input_remain, value) = jppe::decode::<SimpleExample>(input).unwrap();
assert_eq!(value, SimpleExample { length: 3, value: "123".to_string(), cmd: 1, body: SimpleExampleBody::Read { address: 5 } });
assert_eq!(input_remain.is_empty(), true);
assert_eq!(jppe::encode(value), input);
}
Default Example
[dependencies]
jppe = { version="1.1.0", features = ["derive", "jdefault"] }
use jppe::{ByteEncode, ByteDecode, Jdefault};
// If the value size is less than 0xff, byte_count does not need to be specified,otherwise, byte_count=<2|4|8>
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
pub struct SimpleExample {
#[jppe(byte_count=1, default="\"123\".to_string()")]
pub value: String,
#[jppe(byte_count=1)]
pub body: SimpleExampleBody,
}
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
#[repr(u8)]
pub enum SimpleExampleBody {
Read {
address: u8,
} = 1,
Write {
address: u8,
value: [u8; 3],
},
#[jppe(branch_default)]
Unknown {
#[jppe(default=10)]
value: u8,
},
}
fn main() {
let value = SimpleExample::default();
assert_eq!(value, SimpleExample {
value: "123".to_string(),
body: SimpleExampleBody::Unknown { value: 10 },
});
assert_eq!(jppe::encode(value), b"\x03\x31\x32\x33\x03\x0a");
let (input_remain, value) = jppe::decode::<SimpleExample>(b"\x03\x31\x32\x33\x03\x0a").unwrap();
assert_eq!(value, SimpleExample {
value: "123".to_string(),
body: SimpleExampleBody::Unknown { value: 10 },
});
assert_eq!(input_remain.is_empty(), true);
}
Other Example
- tcp_communication_example
- ethernet_example
- ipv4_example
- tcp_example
- http_hashmap_example
- http_vec_example
- parse_example: Including Ethernet/IPv4/TCP/UDP
Feature
ContainerAttrModifiers
-
byteorder=<"BE"|"LE">
: The global byte order of struct and enum, eg:#[jppe(byteorder="LE")]
. -
encode_with
: custom encode function. -
decode_with
: custom decode function. -
with
: custom encode/decode function. -
get_variable_name
: Get cache variable, must be used withvariable_name
, eg: variable_name_example.
enum branch
-
byte_count_disable
-
branch_enum
FieldAttrModifiers
-
byteorder=<"BE"|"LE">
: The byte order of locality field, eg:#[jppe(byteorder="LE")]
-
length=<num|variable>
: Data length, supportint/&str/String/&[u8]
type, eg: length_example. -
offset=<num|variable>
: Byte stream offset. -
count==<num|variable>
: Data count, supportVec/HashMap
type. -
try_count==<num|variable>
: Data count, supportVec/HashMap
type. -
full=<int>
: encode full value. -
untake
: Bytes are not taken. -
linend|end_with=<string|bytes>
: SupportingString/&str/&[u8]
type. -
key|starts_with
: It is suitable for accurate parsing of key/value structure data, supportingstring/&str/&[u8]
types. -
split
: SupportingHashMap
type, eg: split_example -
if_expr
: SupportingOption<T>
type, eg: if_expr_example. -
encode_with
: custom encode function, eg: with_example. -
decode_with
: custom decode function, eg: with_example. -
with
: custom encode/decode function, eg: with_example. -
with_args
: custom encode/decode function args, eg: with_args_example. -
encode_value
: value processing expression, eg:#[jppe(encode_value="length * 2")]
. -
decode_value
: value processing expression, eg:#[jppe(decode_value="length / 2")]
. -
variable_name
: Set integer cache variable, eg: variable_name_example. -
byte_count=<1|2|4|8>
: Specifies the byte count, automatic decode/encode length or other.-
String/&str/&[u8]
: Fetches n byte mapping length in advance, eg: byte_count. -
HexString/HexBytes
: Fetches n byte mapping length in advance, eg: byte_count. -
Enum
: Thebyte_count
byte mapping enumeration is taken in advance and encoded through the enumeration inidex, eg: enum_byte_count -
Vec<T>
-
-
skip
: Require implementDefault
trait for data type. -
skip_encode
: Skip encode function. -
skip_decode
: Require implementDefault
trait for data type. -
check_value
-
default
: eg: default example -
from_str
enum branch
-
branch=<int|variable>
: eg: branch example -
branch_option=<variable>
: eg: branch_option example.rs -
branch_default
: eg: branch_default example -
branch_bits
: eg: branch_bits example -
branch_range
: eg: branch_range example -
branch_value
: eg: branch_value example
DataType
-
u8/u16/u32/u64/usize/u128
-
i8/i16/i32/i64/isize/i128
-
bool
-
f32/f64
-
String
and&str
-
array[T; N]
-
Tuple
-
Vec<T>
-
&[u8]
-
Option<T>
-
Struct
-
Enum
-
PhantomData
-
HashMap
: SupportString/&str/&[u8]
, eg: hashmap_example. -
HashSet<T>
: TheHashSet
type must specify#[jppe(count=xxx)]
modifier, only supporting decode function, defaultcount=0
, eg: hashset_example. -
MacAddress
: eg: mac_example. -
std::net::Ipv4Addr/Ipv6Addr/IpAddr
: IpAddr type requres specifying thelength=<16|4>
modifier, Otherwise return an error, eg: ip_address_example. -
PpeAddress
: Requres specifying thelength=<16|4|6|usize>
modifier, Otherwise return an error, eg: ppe_address_example. -
HexString
: eg: hex_example -
HexBytes
: eg: hex_bytes_example -
DateTime
-
Bit
TODO
- jnet-rs library.
- jget-rs library.
- jdefault-rs library.
- jfmt-rs library.
Dependencies
~0.5–1MB
~21K SLoC