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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use std::cell::RefCell; use std::str::FromStr; use std::rc::Rc; use super::{StoreConst, Store, StoreOption, List, Collect, PushConst}; use super::action::Action; use super::action::{TypedAction, IFlagAction, IArgAction, IArgsAction}; use super::action::ParseResult; use super::action::ParseResult::{Parsed, Error}; use super::action::Action::{Flag, Single, Push, Many}; pub struct StoreConstAction<'a, T: 'a> { pub value: T, pub cell: Rc<RefCell<&'a mut T>>, } pub struct PushConstAction<'a, T: 'a> { pub value: T, pub cell: Rc<RefCell<&'a mut Vec<T>>>, } pub struct StoreAction<'a, T: 'a> { pub cell: Rc<RefCell<&'a mut T>>, } pub struct StoreOptionAction<'a, T: 'a> { cell: Rc<RefCell<&'a mut Option<T>>>, } pub struct ListAction<'a, T: 'a> { cell: Rc<RefCell<&'a mut Vec<T>>>, } impl<T: 'static + Copy> TypedAction<T> for StoreConst<T> { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { let StoreConst(val) = *self; return Flag(Box::new(StoreConstAction { cell: cell, value: val })); } } impl<T: 'static + Copy> TypedAction<Vec<T>> for PushConst<T> { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { let PushConst(val) = *self; return Flag(Box::new(PushConstAction { cell: cell, value: val })); } } impl<T: 'static + FromStr> TypedAction<T> for Store { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { return Single(Box::new(StoreAction { cell: cell })); } } impl<T: 'static + FromStr> TypedAction<Option<T>> for StoreOption { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Option<T>>>) -> Action<'x> { return Single(Box::new(StoreOptionAction { cell: cell })); } } impl<T: 'static + FromStr + Clone> TypedAction<Vec<T>> for List { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { return Many(Box::new(ListAction { cell: cell })); } } impl<T: 'static + FromStr + Clone> TypedAction<Vec<T>> for Collect { fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { return Push(Box::new(ListAction { cell: cell })); } } impl<'a, T: Copy> IFlagAction for StoreConstAction<'a, T> { fn parse_flag(&self) -> ParseResult { let mut targ = self.cell.borrow_mut(); **targ = self.value; return Parsed; } } impl<'a, T: Copy> IFlagAction for PushConstAction<'a, T> { fn parse_flag(&self) -> ParseResult { let mut targ = self.cell.borrow_mut(); targ.push(self.value); return Parsed; } } impl<'a, T: FromStr> IArgAction for StoreAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromStr::from_str(arg) { Ok(x) => { **self.cell.borrow_mut() = x; return Parsed; } Err(_) => { return Error(format!("Bad value {}", arg)); } } } } impl<'a, T: FromStr> IArgAction for StoreOptionAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromStr::from_str(arg) { Ok(x) => { **self.cell.borrow_mut() = Some(x); return Parsed; } Err(_) => { return Error(format!("Bad value {}", arg)); } } } } impl<'a, T: FromStr + Clone> IArgsAction for ListAction<'a, T> { fn parse_args(&self, args: &[&str]) -> ParseResult { let mut result = vec!(); for arg in args.iter() { match FromStr::from_str(*arg) { Ok(x) => { result.push(x); } Err(_) => { return Error(format!("Bad value {}", arg)); } } } **self.cell.borrow_mut() = result; return Parsed; } }