代码拉取完成,页面将自动刷新
这是一个基于Rust实现的字节流结构化序列化/反序列化通用库,可以应用于网络数据包解析、网络数据包组包、网络通信、文件内容解析等,觉得不错的小伙伴们请点个赞👍~
[dependencies]
jppe = { version="1.0.0", features = ["derive"] }
Or
[dependencies]
jppe = { version="1.0.0", features = ["derive", "serde"] }
use jppe::{ByteEncode, ByteDecode};
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub struct SimpleExample {
pub length: u16,
// 这里是指定动态长度,也可以指定固定数值,比如:`#[jppe(length=3)]`
// 还可以不指定`length`, 指定`byte_count=<1|2|4|8>`表示提前取走几个字节根据字节序转为长度数值
#[jppe(length="length")]
pub value: String,
pub cmd: u8,
// 这里指定了branch, 表示根据cmd的值进行枚举类型(enum)模式匹配, 同样也可以指定`byte_count`修饰符
#[jppe(branch="cmd")]
pub body: SimpleExampleBody,
}
#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
#[repr(u8)]
pub enum SimpleExampleBody {
Read {
address: u8,
} = 1, // 这里表示当前面的`cmd`字段为1,则会进入该分支解析
Write {
address: u8,
value: [u8; 3],
}, // 这里如果不指定,默认是递增的关系为2
#[jppe(enum_default)]
Unknown, // 这里由于指定了默认分支,所以会被映射为`_ => { ... }`, 如果没有指定,Unknown序号为3,其他则会返回解析错误
}
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);
}
[dependencies]
jppe = { version="1.0.0", features = ["derive", "jdefault"] }
use jppe::{ByteEncode, ByteDecode, Jdefault};
// 如果值长度小于0xff, 则可以不用指定byte_count=1, 否则需要指定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);
}
主要用于修饰某个struct/enum全局定义,表示struct/enum里面的字段都遵循,也可以通过FieldAttrModifiers
修饰单个内容。
通用修饰符
byteorder=<"BE"|"LE">
: 这是struct/enum类型全局字节序,BE(大端字节序)/LE(小端字节序), eg: #[jppe(byteorder="LE")]
.encode_with
: 自定义encode函数, eg: with_encode_example.decode_with
: 自定义decode函数, eg: with_decode_example.with
: 自定义encode/decode函数, eg: with_encode_example.get_variable_name
: 获取缓存变量, 必须配合variable_name
使用,可以用于不用struct或enum类型传递, eg: variable_name_example.枚举分支修饰符
branch_enum
主要用于修饰struct/enum里面某个字段内容
byteorder=<"BE"|"LE">
: 这是struct/enum类型局部字段字节序,BE(大端字节序)/LE(小端字节序), eg: #[jppe(byteorder="LE")]
length=<num|variable>
: 数据长度, 支持int/&str/String/&[u8]
类型, eg: length_example.offset=<num|variable>
: 字节流偏移,表示跳过几个字节.count==<num|variable>
: 数据条目数量, 支持Vec/HashMap
类型.full=<int>
: 主要用于encode填充值, 默认为0, 常常用于offset偏移之后进行encode编码填充.untake
: 表示解析内容, 但是不取走字节, 后面的解析任然可以读取该字节.linend|end_with=<string|bytes>
: 指定结束位置, 支持String/&str/&[u8]/HashMap
等类型.key|starts_with
: 指定精准匹配关键字, 必须配合linend
使用, 支持string/&str/&[u8]
等类型.split
: 指定分隔符, 常常用于Key: Value
这种内容, 支持HashMap
类型, eg: split_example
if_expr <bool expr>
: 指定if表达式, 支持Option<T>
类型, eg: if_expr_example.encode_with
: 自定义encode函数, eg: with_example.decode_with
: 自定义decode函数, eg: with_example.with
: 自定义encode/decode函数, eg: with_example.with_args
: 自定义encode/decode函数参数, eg: with_args_example.encode_value
: value处理表达式, eg: #[jppe(encode_value="length * 2")]
.decode_value
: value处理表达式, eg: #[jppe(decode_value="length / 2")]
.variable_name
: 指定整型类型缓存变量, eg: variable_name_example.byte_count=<1|2|4|8>
: 指定byte_count
字节数量, 会取走对应字节映射数字, 常常用于下面类型:
String/&str/&[u8]
: 提前取n个字节映射长度, eg: byte_count.HexString/HexBytes
: 提前取n个字节映射长度, eg: byte_count.Enum
: 提前取n个字节映射枚举索引, eg: enum_byte_count.Vec<T>
skip
: 数据类型需要实现Default
trait.skip_encode
: 跳过encode函数.skip_decode
: 数据类型需要实现Default
trait.check_value
:主要用于检查结果是否正常, 异常会返回错误default
: eg: default example
enum branch
branch
: 指定枚举(Enum)类型分支条件: branch example
branch
: 指定枚举(Enum)类型分支条件: branch_option example
branch_default|enum_default
: 指定枚举(Enum)类型默认值, eg: branch_default example
branch_bits
: 指定枚举(Enum)分支判断条件, eg: branch_bits example
branch_range
: 指定枚举(Enum)分支判断条件范围, eg: branch_range example
branch_value
: 指定枚举(Enum)分支判断条件, eg: branch_value example
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
: 支持String/&str/&[u8]
类型, 可以指定#[jppe(count=xxx)]
修饰符表示解析数量, 默认是50
, eg: hashmap_example.HashSet<T>
: 需要指定#[jppe(count=xxx)]
修饰符表示解析数量, 仅仅支持decode函数, 默认count=0
, eg: hashset_example.MacAddress
: 内部实现MacAddress类型, eg: mac_example.std::net::Ipv4Addr
: Ipv4类型.std::net::Ipv6Addr
: Ipv6类型.std::net::IpAddr
: 必须指定length=<16|4>
修饰符, 否则返回错误, eg: ip_address_example.PpeAddress
: 内部实现PpeAddress类型, 包含IPv4/IPv6/Mac/Usize
地址类型, 必须指定length=<16|4|6|usize>
修饰符, 否则返回错误, eg: ppe_address_example.HexString
: 内部实现HexString
类型, eg: hex_example
HexBytes
: 内部实现HexBytes
类型, HexBytes
引用类型, eg: hex_bytes_example
DateTime
Bit
jnet-rs
: 基于jppe
实现常见网络协议结构化定义.jget-rs
: 通过修饰符暴露pub fn get_xxxx(&self) -> xxxx
函数,避免手动定义.jdefault-rs
:通过修饰符设置默认值, 可以集合jppe
结构化定义实现默认值编码功能.jfmt-rs
: 主要用于格式化jppe
定义结构化内容数据.此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。