7 个不稳定版本 (3 个重大更改)
使用旧的 Rust 2015
0.3.0 | 2015年8月9日 |
---|---|
0.2.0 | 2015年7月30日 |
0.1.0 | 2015年7月22日 |
0.0.5 | 2015年7月21日 |
#4 in #nue
7KB
#[derive(..)]
属性用于 POD 和二进制可编码类型。
属性
#[packed]
应用 #[repr(Packed)]
属性,同时确保所有成员都可以安全地进行非对齐访问。
#![feature(plugin, custom_derive, custom_attribute)]
#![plugin(nue_macros)]
extern crate nue;
use nue::{Pod, Aligned, Un};
#[packed]
struct Data(u8, Un<u32>);
let data = Data(5, 5.unaligned());
assert_eq!(data.0, 5u8);
assert_eq!(u32::aligned(data.1), 5u32);
#[derive(Pod)]
将结构体标记为 pod::Pod
。它只能包含其他 Pod
成员,并且类型必须是打包的。
#[derive(PodPacked)]
将结构体标记为 pod::Pod
,并应用 #[packed]
属性到类型上。
示例
#![feature(plugin, custom_derive, custom_attribute)]
#![plugin(nue_macros)]
extern crate pod;
extern crate nue;
use pod::Pod;
#[derive(Pod)]
#[packed]
struct Data(u8);
assert_eq!(Data(5).as_slice(), &[5]);
#[derive(NueEncode,NueDecode)]
在结构体上实现 nue::Encode
和 nue::Decode
。所有字段也必须实现 Encode
/ Decode
(或通过 nue
属性跳过)。
#[nue(...)]
,#[nue_enc(...)]
,#[nue_dec(...)]
每个字段都可能使用nue
属性提供额外的编码选项。它们将影响父类型的编码或解码方式。这些属性接受任意的Rust表达式。可以通过self
访问成员变量。
nue_enc
仅适用于编码,nue_dec
适用于解码,而nue
适用于两者。尽管属性的顺序通常不重要,但align
和skip
的交互方式取决于哪个先定义。
assert
在继续操作之前,断言某些属性为真。
use nue::Decode;
#[derive(NueDecode)]
struct Data(
#[nue(assert = "self.0 == 0")]
u8
);
let data = &[1];
assert!(&Data::decode_slice(data).is_err());
let data = &[0];
assert!(&Data::decode_slice(data).is_ok());
align
将字段对齐到给定倍数的偏移量。
use nue::Encode;
#[derive(NueEncode)]
struct Data(
u8,
#[nue(align = "self.0 as u64 + 1")]
&'static str
);
let data = Data(2, "hi");
let cmp = &[2, 0, 0, b'h', b'i'];
assert_eq!(&data.encode_vec().unwrap(), cmp);
skip
在编码/解码值之前丢弃指定数量的字节。
use nue::Encode;
#[derive(NueEncode)]
struct Data(
u8,
#[nue(skip = "1")]
&'static str
);
let data = Data(2, "hi");
let cmp = &[2, 0, b'h', b'i'];
assert_eq!(&data.encode_vec().unwrap(), cmp);
cond
有条件地编码或解码字段。如果条件不满足,将使用Default::default()
。使用false
是静态保证忽略该字段。
use nue::Encode;
#[derive(NueEncode)]
struct Data<'a>(
u8,
#[nue(cond = "false")]
&'a () // Note that this type does not implement `Encode`
);
let u = ();
let data = Data(2, &u);
let cmp = &[2];
assert_eq!(&data.encode_vec().unwrap(), cmp);
default
确定在cond
评估为假时使用的默认值。
use nue::Decode;
#[derive(NueDecode, PartialEq, Debug)]
struct Data(
u8,
#[nue(cond = "self.0 == 1", default = "5")]
u8
);
let data = &[2];
assert_eq!(&Data::decode_slice(data).unwrap(), &Data(2, 5));
let data = &[1, 2];
assert_eq!(&Data::decode_slice(data).unwrap(), &Data(1, 2));
limit
限制编码过程中可以消耗或写入的字节数量。
use nue::Decode;
#[derive(NueDecode)]
struct Data(
#[nue(limit = "4")]
String,
);
let data = b"hello";
assert_eq!(&Data::decode_slice(data).unwrap().0, "hell");
consume
当设置时,即使类型没有编码或解码整个字节区域,也会使用所有的limit
。
use nue::Decode;
use std::ffi::CString;
#[derive(NueDecode)]
struct Data(
#[nue(limit = "8", consume = "true")]
CString,
u8
);
let data = b"hello\0\0\0\x05";
let data = Data::decode_slice(data).unwrap();
assert_eq!(data.0.to_bytes(), b"hello");
assert_eq!(data.1, 5);