Destruct
Destruct structs and enums into a heterogeneous list consists of a fixed set of types, to enable a quick implementation of combinator libraries.
API
trait Destruct
type DestructType
The destructed object type
If your struct is:
Then the DestructType is:
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`
}
Here is a list of types may appear in DestructType:
- DestructBegin
- DestructField
- DestructEnd
- DestructEnumBegin
- DestructEnumVariant
- DestructEnumEnd
fn destruct(self) -> Self::DestructType
Destruct self to destruct type
fn construct(d: Self::DestructType) -> Self;
Construct self from destruct type
Metadata
Example
For example, here is how to implement a parser with destruct (see destruct-parser
):
- Write a
Parsable
trait; - Implement parsers for basic types;
- Implement parsers for six Destruct types;
- Derive
Destruct
for your struct by adding#[derive(Destruct)]
- (Optional) Implement a macro for deriving
impl<T: Destruct> Parsable
, namelyparsable!
; - (Optional) Implement
Parsable
for your struct by adding#[destruct(parsable)]
Why do I need parsable!
macro?
Because Rust forbids overlapping implementation of traits. Ideally what I need is the following trait implementation:
But Rust complains:
upstream crates may add new impl of trait `destruct::Destruct` for type `destruct::DestructEnumBegin<_, _>` in future versions
So I added #[destruct(parsable)]
to generate impls for every struct. It is equivalent to parsable!(YourStruct)
.
Limitations
Generics are not supported.