3 releases

0.1.2 Jul 16, 2024
0.1.1 Jan 14, 2023
0.1.0 Jan 12, 2023

#356 in Procedural macros

MIT/Apache

36KB
817 lines

Macro to implement inherit

Provide class to cover a struct itself, it's impl and trait implements that need to inherit. To borrow as mut, see def_as_mut

macro class

need to wrap struct and implements.

using #[keep] for method make that method keep in the original impl.

methods without #[keep] will be put into trait __XXX__.

and macro will auto generate a new function which return Pin<Box>.

expression in the method will be converted.

instead of use self, using this.

self will be convert to use unsafe { self.__real__.as_ref().unwrap() }.

self_mut will be convert to use unsafe { self.__real__.as_mut().unwrap() }.

_super will be convert to use self.__prototype__.

_super_mut will be convert to use unsafe { self.__prototype__.as_mut().get_unchecked_mut() }.

macro def_as_mut

this macro will define macro as_mut

example:

class! {
    struct Example {
        data: String    
    }
    impl Example {
        #[keep]
        fn with() -> Pin<Box<Self>> where Self: Sized {
            Self::new("example".to_string())
        }
        
        fn set_data(&mut self, data: String) {
            this.data = data;
        }

        fn get_data(&self) -> String {
            this.data.clone()
        }
    }
    impl Something for Example {
        //do something
    }
}
class! {
    extends Example;
    struct Sub { }
    impl Sub { }
}

the struct will become:

struct Example {
    __real__: *mut dyn __Example__,
    _pinned: ::std::marker::PhantomPinned,
    data: String
}
struct Sub {
    __prototype__: ::std::pin::Pin<Box<Example>>
    __real__: *mut dyn __Sub__,
    _pinned: ::std::marker::PhantomPinned,
}

to borrow as mut:

def_as_mut!();

fn main() {
    let mut example = Sub::new("data".to_string());
    as_mut!(example).set_data("modified".to_string());
    assert_eq!(example.get_data(), "modified".to_string());
}

Dependencies

~1.5MB
~36K SLoC