1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#[macro_export] macro_rules! emit { ($action:expr) => { yield $action; () }; } #[macro_export] macro_rules! select { ($action:expr) => { match yield $action { UserAction::SelectItem(m, i) => (m, i), _ => return, } }; } #[macro_export] macro_rules! generator { ($name:ident, $code:block) => { use $crate::{ action::{ActionResult, GeneratorAction, UserAction}, mode::Mode, }; pub struct $name { message: Option<String>, items: Vec<String>, generator: Box<dyn Generator<UserAction, Return = (), Yield = GeneratorAction> + Unpin>, } impl Default for $name { fn default() -> Self { let mut generator = Box::new(move |_| $code); let state = Pin::new(&mut generator).resume(UserAction::EnterMenu); let mut items = Vec::new(); let message; match state { GeneratorState::Yielded(action) => match action { GeneratorAction::ReplaceItems(new_message, new_items) => { message = new_message; items = new_items; } GeneratorAction::Default => message = None, }, _ => message = Some("Plugin exited right after start".into()), }; GeneratorRofi { message, items, generator, } } } impl Mode for $name { fn len(&self) -> usize { self.items.len() } fn name(&self, line: usize) -> &str { &self.items[line] } fn action(&mut self, action: UserAction) -> ActionResult { let action = Pin::new(&mut self.generator).resume(action); match action { GeneratorState::Yielded(GeneratorAction::ReplaceItems(msg, items)) => { self.message = msg; self.items = items; ActionResult::Reset } _ => ActionResult::Exit, } } fn message(&self) -> Option<&str> { self.message.as_ref().map(|f| f as &str) } } }; }