3个版本
0.1.2 | 2019年11月7日 |
---|---|
0.1.1 | 2019年10月15日 |
0.1.0 | 2019年10月15日 |
在#destruct中排名第6
在 2 crate中使用
21KB
471 行
Destruct
将Destruct结构和枚举分解为包含一组固定类型的异构列表,以快速实现组合器库。
API
trait Destruct
type DestructType
分解的对象类型
如果你的结构是
#[derive(Destruct)]
struct YourStruct {
field: YourField,
field2: YourField2,
}
则DestructType是
DestructBegin<Fields, m>
where Fields = DestructField<YourField, NextField, m1>
NextField = DestructField<YourField2, End, m2>
End = DestructEnd<m>
where m is some generated type implementing `trait DestructMetadata`
m1 is the metadata for `field`, implementing `trait DestructFieldMetadata + DestructMetadata`
m2 is the metadata for `field2`, implementing `trait DestructFieldMetadata + DestructMetadata`
}
以下是DestructType可能出现的类型列表
- DestructBegin
- DestructField
- DestructEnd
- DestructEnumBegin
- DestructEnumVariant
- DestructEnumEnd
fn destruct(self) -> Self::DestructType
将self分解为分解类型
fn construct(d: Self::DestructType) -> Self;
从分解类型构造self
元数据
pub trait DestructMetadata {
fn struct_name() -> &'static str;
fn named_fields() -> bool;
}
pub trait DestructFieldMetadata: DestructMetadata + 'static {
fn field_name() -> &'static str;
fn field_index() -> usize;
}
pub trait DestructEnumMetadata {
fn enum_name() -> &'static str;
}
pub trait DestructEnumVariantMetadata: DestructEnumMetadata + 'static {
fn variant_name() -> &'static str;
fn variant_index() -> usize;
}
示例
例如,以下是如何使用Destruct实现解析器(参见 destruct-parser
)
- 编写一个
Parsable
trait; - 实现基本类型的解析器;
- 实现六种Destruct类型的解析器;
- 通过添加
#[derive(Destruct)]
为你的结构派生Destruct
; - (可选) 实现一个派生
impl<T: Destruct> Parsable
的宏,即parsable!
; - (可选) 通过添加
#[destruct(parsable)]
为你的结构实现Parsable
;
为什么需要parsable!
宏?
因为Rust禁止重叠实现特性。理想情况下我需要以下特性实现
impl<T: Destruct> Parsable for T where T::DestructType: Parsable {}
但是Rust报错
upstream crates may add new impl of trait `destruct::Destruct` for type `destruct::DestructEnumBegin<_, _>` in future versions
因此,我添加了 #[destruct(parsable)]
以生成每个结构的impl。它等价于 parsable!(YourStruct)
。
#[macro_export]
macro_rules! parsable {
($t:ident) => {
impl Parsable for $t {
fn parse<R: io::Read + Clone>(read: &mut R) -> Result<Self, Error> {
<$t as Destruct>::DestructType::parse(read).map(<$t as Destruct>::construct)
}
}
};
}
限制
泛型不支持。
依赖项
~1.5MB
~35K SLoC