2 个不稳定版本
0.1.0 | 2022 年 3 月 15 日 |
---|---|
0.0.1 | 2022 年 3 月 8 日 |
#1581 in Rust 模式
在 3 个 crate 中使用 (通过 pk_compiler)
13KB
117 代码行
bytecoding
用于将指令和操作数编码和解码为字节码的派生宏。
文档
许可
许可协议为 Apache License, Version 2.0 或 MIT License,任选其一。
除非您明确声明,否则任何有意提交给此 crate 的贡献,根据 Apache-2.0 许可协议,将按照上述方式双许可,不附加任何额外条款或条件。
lib.rs
:
用于将指令和操作数编码和解码为字节码的派生宏。
派生宏
枚举属性
可以用于枚举的属性。
-
type = ...
(必需)设置用于指令代码的类型。可能的值有
u8
、u16
、u32
和u64
。
变体属性
可以用于枚举变体的属性。
-
code= ...
设置此枚举变体的指令代码。每个变体生成的指令都需要指定一个代码。如果变体只生成一个指令,则可以使用单个数字作为
code
属性(而不是数字列表)。
变体字段属性
可以用于枚举变体字段的属性。
-
flatten= [...]
将字段展平为每指定值的指令代码。此属性旨在用于优化某些值,对于任何未指定的值则回退到使用操作数。如果您想展平所有值,请使用
flatten_all
属性。请参阅下面的 示例 了解如何使用此属性。
-
flatten_all= [...]
将枚举变体展平为每指定值的指令代码。请注意,必须指定所有可能的值。如果您只想展平某些值,请使用
flatten
属性。请参阅下面的 示例 了解如何使用此属性。
字段属性
可以用于结构字段或枚举变体字段的属性。
-
skip
跳过字段的编码和解码。解码时使用
std::default::Default
的值。
示例
use bytecoding::Bytecode;
#[derive(Debug, PartialEq, Eq, Bytecode)]
struct Operand {
value1: u8,
value2: u16,
}
#[derive(Debug, PartialEq, Eq, Bytecode)]
#[bytecode(type = u8)]
enum Instruction {
Add,
Sub,
Jump(u8),
Foo(Operand),
// This generates four instruction codes without an operand for the values 0 to 3, and one
// instruction code with an operand for all remaining values
Const {
#[bytecode(flatten = [0, 1, 2, 3])]
index: u16,
},
// This generates two instruction codes (without an operand):
// - The first code is for the value `true`
// - The second code is for the value `false`
Bool(#[bytecode(flatten_all = [true, false])] bool),
}
let instructions = vec![
Instruction::Sub,
Instruction::Add,
Instruction::Foo(Operand { value1: 20, value2: 30 }),
Instruction::Jump(42),
Instruction::Const { index: 0 },
Instruction::Const { index: 4 },
Instruction::Bool(true),
Instruction::Bool(false),
];
// Encoding
let mut buf = Vec::new();
for instruction in &instructions {
instruction.encode(&mut buf);
}
assert_eq!(buf, vec![
1, // Sub
0, // Add
3, 20, 0, 30, // Foo(Operand { value1: 20, value2: 30 })
2, 42, // Jump(42)
4, // Const { index: 0 }
8, 0, 4, // Const { index: 4 }
9, // Bool(true)
10, // Bool(false)
]);
// Decoding
let mut buf: &[u8] = &buf;
let mut decoded_instructions = Vec::new();
while !buf.is_empty() {
decoded_instructions.push(Instruction::decode(&mut buf)?);
}
assert_eq!(decoded_instructions, instructions);
依赖项
~2.5MB
~51K SLoC