wraps 1.0.0

create marker types that wrap other, inner, types - with trait impls matching PhantomData
Documentation
  • Coverage
  • 100%
    2 out of 2 items documented1 out of 1 items with examples
  • Size
  • Source code size: 25.19 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 606.59 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 13s Average build duration of successful builds.
  • all releases: 13s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • infomorphic-matti/wraps
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • infomorphic-matti

wraps

Simple Rust macro for creating marker types that also encode some "inner type information" as a type argument - essentially like PhantomData - and that implement traits such as Default and Debug for all type arguments rather than just type arguments that themselves implement the relevant traits (as would occur if you used the #[derive] annotation).

Designed for use in creating wrapper types for use inside marker types in a more advanced version of the pattern observed in bevy_ecs, where wrapper types are used to disambiguate relevant traits or properties of some subcomponent of the marker type.

You could also create wrapper types fairly simply without any macro but it's slightly more cumbersome - and if you want the structure to be exactly like PhantomData - for example, having universal implementations of traits like Debug, Copy and Clone that don't require the type argument to implement those traits - then it takes a lot of boilerplate code that this crate will create for you automatically.

Example Usage

trait PropertyA {
    fn a(&self);
}
trait PropertyB {
    fn b(&self);
}

mod marker {
    wraps::marker! {
        /// Interpret type as implementing [`super::PropertyA`], inner field 
        /// is public.
        pub(crate) struct PropertyA;
        /// Interpret type as implementing [`super::PropertyB`], inner field 
        /// is not public.
        pub struct PropertyB<MyTypeName>;
        /// Interpret type as mysterious property C with default type being `()`, 
        /// inner field is public.
        pub struct PropertyC<pub Weird = ()>;
    }
}

pub trait AnswerMyQuestion<M> {
    fn emit_properties(&self);
}

impl <T: PropertyA, Q: PropertyB> 
    AnswerMyQuestion<(marker::PropertyA<T>, marker::PropertyB<Q>)> for (T, Q) 
{
    fn emit_properties(&self) {
        self.0.a(); 
        self.1.b();
    }    
} 


impl <T: PropertyB, Q: PropertyA> 
    AnswerMyQuestion<(marker::PropertyB<T>, marker::PropertyA<Q>)> for (T, Q) 
{
    fn emit_properties(&self) {
        self.0.b(); 
        self.1.a();
    }    
} 

License

This crate is licensed under MPL-2.0.