# Extractor A procedural macro generate the trait for [`extactor pattern`](https://github.com/alexpusch/rust-magic-patterns/blob/master/axum-style-magic-function-param/Readme.md). # Example ```rust #[derive(Debug)] pub struct Widget<'a, V> { val: &'a V, } impl<'a, V> ExtractInnerA<'a, V> for Widget<'a, V> { fn inner(&self) -> &'a V { self.val } } impl<'a> Extract<'a, i64, Widget<'a, i64>> for &'a i64 { type Output<'b> = &'b i64 where i64: 'b; type Error = String; fn extract(_uid: u64, set: &Widget<'a, i64>) -> Result, Self::Error> { Ok(set.inner()) } } impl<'a> Extract<'a, i64, Widget<'a, i64>> for String { type Output<'b> = String where i64: 'b; type Error = String; fn extract(_uid: u64, set: &Widget<'a, i64>) -> Result, Self::Error> { Ok(set.inner().to_string()) } } fn wrap_handler<'a, V, H, S, Args>(mut handler: H) -> impl FnMut(u64, &S) -> Result<(), String> + 'a where V: 'a, S: ExtractInnerA<'a, V> + 'a, H: Handler + 'a, Args: Extract<'a, V, S, Output<'a> = Args>, { Box::new(move |uid: u64, set: &S| { let args = Args::extract(uid, set).map_err(|v| v.into())?; handler.handle(uid, set, args) }) } // generate extract and handler trait extpat::extract!(err: String, Extract { uid: u64, set: &A }); extpat::handler!(err: String, Handler { uid: u64, set: &A }); fn main() { fn annoy1<'a>(uid: u64, w: &Widget<'a, i64>, val: &'a i64) -> Result<(), String> { println!("---> in annoy1: uid = {}, widget = {:?}, {}", uid, w, val); Ok(()) } fn annoy2(uid: u64, w: &Widget<'_, i64>, val: String) -> Result<(), String> { println!("---> in annoy2: uid = {}, widget = {:?}, {}", uid, w, val); Ok(()) } type HandlerT<'a> = Box) -> Result<(), String> + 'a>; let value = Widget { val: &42i64 }; let handler: Vec> = vec![ Box::new(wrap_handler(annoy1)), Box::new(wrap_handler(annoy2)), ]; for mut h in handler { h(0, &value).unwrap(); } } ```