parser_ext.rs
1 use crate::matrix::commands::{CommandError, CommandResult, parser::ParsedCommand}; 2 3 pub const ARG_YEAR: &str = "year"; 4 pub const ARG_DAY: &str = "day"; 5 pub const ARG_ROWS: &str = "rows"; 6 pub const ARG_OFFSET: &str = "offset"; 7 8 pub trait ParserExt { 9 fn parse_year(&mut self, max_year: i32) -> CommandResult<Option<i32>>; 10 fn parse_year_default_most_recent(&mut self, most_recent_year: i32) -> CommandResult<i32> { 11 Ok(self 12 .parse_year(most_recent_year)? 13 .unwrap_or(most_recent_year)) 14 } 15 16 fn parse_day(&mut self) -> CommandResult<Option<u32>>; 17 fn parse_day_required(&mut self, default: Option<u32>) -> CommandResult<u32> { 18 self.parse_day()? 19 .or(default) 20 .ok_or(CommandError::ArgRequired(ARG_DAY)) 21 } 22 23 fn parse_rows(&mut self) -> CommandResult<Option<usize>>; 24 fn parse_offset(&mut self) -> CommandResult<usize>; 25 } 26 27 impl<'a> ParserExt for ParsedCommand<'a> { 28 fn parse_year(&mut self, max_year: i32) -> CommandResult<Option<i32>> { 29 self.get_from_kwargs_or_args(ARG_YEAR) 30 .map(|s| { 31 s.parse() 32 .ok() 33 .filter(|year| (2015..=max_year).contains(year)) 34 .ok_or(CommandError::ArgParse { 35 arg: ARG_YEAR, 36 allowed_values: Some(format!("2015, ..., {max_year}").into()), 37 }) 38 }) 39 .transpose() 40 } 41 42 fn parse_day(&mut self) -> CommandResult<Option<u32>> { 43 self.get_from_kwargs_or_args(ARG_DAY) 44 .map(|x| x.parse()) 45 .transpose() 46 .map_err(|_| CommandError::ArgParse { 47 arg: ARG_DAY, 48 allowed_values: None, 49 }) 50 } 51 52 fn parse_rows(&mut self) -> CommandResult<Option<usize>> { 53 self.get_from_kwargs_or_args(ARG_ROWS) 54 .map(|x| { 55 x.parse() 56 .ok() 57 .filter(|rows| (1..=200).contains(rows)) 58 .ok_or(CommandError::ArgParse { 59 arg: ARG_ROWS, 60 allowed_values: Some("1, ..., 200".into()), 61 }) 62 }) 63 .transpose() 64 } 65 66 fn parse_offset(&mut self) -> CommandResult<usize> { 67 Ok(self 68 .get_from_kwargs_or_args(ARG_OFFSET) 69 .map(|x| { 70 x.parse() 71 .ok() 72 .filter(|offset| (0..=200).contains(offset)) 73 .ok_or(CommandError::ArgParse { 74 arg: ARG_OFFSET, 75 allowed_values: Some("0, ..., 200".into()), 76 }) 77 }) 78 .transpose()? 79 .unwrap_or(0)) 80 } 81 }