Macro define_accessor_trait

Source
macro_rules! define_accessor_trait {
    {
        $( #[ $attr:meta ])*
        $vis:vis trait $Trait:ident $( : $( $Super:path )* )? {
            $( $accessor:ident: $type:ty, )*
            $( + $( $rest:tt )* )?
        }
    } => { ... };
}
Expand description

Define an “accessor trait”, which describes structs that have fields of certain types

This can be useful if a large struct, living high up in the dependency graph, contains fields that lower-lever crates want to be able to use without having to copy the data about etc.

// imagine this in the lower-level module
pub trait Supertrait {}
use tor_basic_utils::define_accessor_trait;
define_accessor_trait! {
    pub trait View: Supertrait {
        lorem: String,
        ipsum: usize,
        +
        fn other_accessor(&self) -> bool;
        // any other trait items can go here
   }
}

fn test_view<V: View>(v: &V) {
    assert_eq!(v.lorem(), "sit");
    assert_eq!(v.ipsum(), &42);
}

// imagine this in the higher-level module
use derive_more::AsRef;
#[derive(AsRef)]
struct Everything {
    #[as_ref] lorem: String,
    #[as_ref] ipsum: usize,
    dolor: Vec<()>,
}
impl Supertrait for Everything { }
impl View for Everything {
    fn other_accessor(&self) -> bool { false }
}

let everything = Everything {
    lorem: "sit".into(),
    ipsum: 42,
    dolor: vec![()],
};

test_view(&everything);

§Generated code

pub trait View: AsRef<String> + AsRef<usize> + Supertrait {
    fn lorem(&self) -> &String { self.as_ref() }
    fn ipsum(&self) -> &usize { self.as_ref() }
}