[−][src]Crate structural
This library provides abstractions over fields,emulating structural types.
Features
These are the features this library provides:
-
Derivation of per-field accessor traits (GetField/GetFieldMut/IntoField).
-
Declaration of trait aliases for the field accessor traits .
Examples
Structural Derive
This demonstrates how you can use any type with a superset of the fields of another one in a function.
For details on the Structural derive macro look here.
use structural::{GetFieldExt,Structural,ti}; #[derive(Structural)] // Using the `#[struc(public)]` attribute tells the derive macro to // generate the accessor trait impls for non-`pub` fields. #[struc(public)] struct Point3D<T>{ x:T, y:T, z:T, } fn reads_point4<S>(point:&S) where // The `Structural` derive macro generated the `Point3D_SI` trait, // aliasing the accessor traits for Point3D. S:Point3D_SI<u32> { let (a,b,c)=point.fields(ti!(x,y,z)); assert_eq!(a,&0); assert_eq!(b,&11); assert_eq!(c,&33); } ////////////////////////////////////////////////////////////////////////// //// In another crate #[derive(Structural)] #[struc(public)] // Using the `#[struc(access="mut move")]` attribute tells the derive macro to // generate the accessor trait for accessing the // fields by reference/mutable-reference/by value, // when by default it only impls the by-reference one. #[struc(access="mut move")] struct Point4D<T>{ x:T, y:T, z:T, a:T, } #[derive(Structural)] #[struc(public)] // Using the `#[struc(access="move")]` attribute tells the derive macro to // generate the accessor trait for accessing the // fields by reference/by value,when by default it only impls the by-reference one. #[struc(access="move")] struct Point5D<T>{ x:T, y:T, z:T, a:T, b:T, } reads_point4(&Point3D { x: 0, y: 11, z: 33 }); reads_point4(&Point4D { x: 0, y: 11, z: 33, a: 0xDEAD, }); reads_point4(&Point5D { x: 0, y: 11, z: 33, a: 0xDEAD, b: 0xBEEF, });
Structural alias
This demonstrates how you can define a trait alias for a single read-only field accessor.
For more details you can look at the docs for the
structural_alias
macro.
use structural::{GetFieldExt,Structural,structural_alias,ti}; use std::borrow::Borrow; structural_alias!{ trait Person<S>{ name:S, } } fn print_name<T,S>(this:&T) where T:Person<S>, S:Borrow<str>, { println!("Hello, {}!",this.field_(ti!(name)).borrow() ) } // most structural aliases are object safe fn print_name_dyn< S>(this:&dyn Person<S>) where S:Borrow<str>, { println!("Hello, {}!",this.field_(ti!(name)).borrow() ) } ////////////////////////////////////////////////////////////////////////// //// The stuff here could be defined in a separate crate #[derive(Structural)] // Using the `#[struc(public)]` attribute tells the derive macro to // generate the accessor trait impls for non-`pub` fields. #[struc(public)] struct Worker{ name:String, salary:Cents, } #[derive(Structural)] #[struc(public)] struct Student{ name:String, birth_year:u32, } fn main(){ let worker=Worker{ name:"John Doe".into(), salary:Cents(1_000_000_000_000_000), }; let student=Student{ name:"Jake English".into(), birth_year:1995, }; print_name(&worker); print_name(&student); print_name_dyn(&worker); print_name_dyn(&student); }
Anonymous structs (make_struct
macro)
This demonstrates how you can construct an anonymous struct.
For more details you can look at the docs for the
make_struct
macro.
use structural::{GetFieldExt,make_struct,structural_alias,ti}; structural_alias!{ trait Person<T>{ // We only have shared access (`&String`) to the field. name:String, // We have shared,mutable,and by value access to the field. mut move value:T, } } fn print_name<T>(mut this:T) where T:Person<Vec<String>>, { println!("Hello, {}!",this.field_(ti!(name)) ); let list=vec!["what".into()]; *this.field_mut(ti!(value))=list.clone(); assert_eq!( this.field_(ti!(value)), &list ); assert_eq!( this.into_field(ti!(value)), list ); } // most structural aliases are object safe fn print_name_dyn(mut this:Box<dyn Person<Vec<String>>>){ println!("Hello, {}!",this.field_(ti!(name)) ); let list=vec!["what".into()]; *this.field_mut(ti!(value))=list.clone(); assert_eq!( this.field_(ti!(value)), &list ); assert_eq!( this.box_into_field(ti!(value)), list ); } ////////////////////////////////////////////////////////////////////////// //// The stuff here could be defined in a separate crate fn main(){ let worker=make_struct!{ // This derives clone for the anonymous struct #![derive(Clone)] name:"John Doe".into(), salary:Cents(1_000_000_000_000_000), value:vec![], }; let student=make_struct!{ // This derives clone for the anonymous struct #![derive(Clone)] name:"Jake English".into(), birth_year:1995, value:vec![], }; print_name(worker.clone()); print_name(student.clone()); print_name_dyn(Box::new(worker)); print_name_dyn(Box::new(student)); } #[derive(Debug,Copy,Clone,PartialEq,Eq)] struct Cents(u64);
Re-exports
pub use crate::field_traits::GetField; |
pub use crate::field_traits::GetFieldMut; |
pub use crate::field_traits::IntoField; |
pub use crate::field_traits::IntoFieldMut; |
pub use crate::field_traits::GetFieldExt; |
pub use crate::field_traits::GetFieldType; |
pub use crate::structural_trait::Structural; |
pub use crate::structural_trait::StructuralDyn; |
Modules
chars | Type-level ascii characters and bytes. |
docs | Documentation for proc-macros and guides. |
field_traits | Accessor and extension traits for fields. |
mut_ref | A wrapper type for a mutable pointer with a lifetime. |
reexports | Reexports from the |
structural_trait | Contains the Structural trait with info about the fields that have accessor trait impls. |
type_level | Contains types representing values. |
utils | Some helper functions. |
Macros
TI | Constructs a type-level identifier for use as a generic parameter. |
TList | Type macro for a type-list. |
declare_names_module | Declares a module with aliases for type-level idents,used to access fields. |
delegate_structural_with | This macro allows delegating the implementation of the Structural and field accessor traits. |
impl_box_into_field_method | For use in manual implementations of the IntoField trait. |
impl_structural_dyn | Implements StructuralDyn for some type,by delegating to Structural. |
make_struct | Constructs an anonymous struct,
which implements the |
structural_alias | The |
ti | Constructs field identifier(s) (TString/TStringSet). |
tlist | Instantiates a type-list, which is a zero-sized-type which does not contain instances of the types it lists. |
unsafe_impl_get_field_raw_mut_method | For manual implementors of the GetFieldMut trait, implementing the methods used for accession multiple mutable fields. |
Derive Macros
Structural | This macro is documented in structural::docs::structural_macro |