SHARE
TWEET

Untitled

a guest May 19th, 2019 70 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use std::collections::HashMap;
  2. use std::iter::Peekable;
  3. use std::slice::Iter;
  4. use std::str::Chars;
  5.  
  6. pub struct CommandLine<'a> {
  7.     commands: HashMap<&'a str, Command<'a>>,
  8. }
  9.  
  10. impl<'a> CommandLine<'a> {
  11.     pub fn new_appending(commands: HashMap<&'a str, Command<'a>>) -> Self {
  12.         Self { commands }
  13.     }
  14.  
  15.     pub fn new() -> Self {
  16.         Self {
  17.             commands: HashMap::new(),
  18.         }
  19.     }
  20.  
  21.     pub fn register(&mut self, command: Command<'a>) {
  22.         self.commands.insert(command.name, command);
  23.     }
  24.  
  25.     pub fn deregister(&mut self, command: Command<'a>) {
  26.         self.commands.remove(command.name);
  27.     }
  28.  
  29.     pub fn lookup(&self, name: &str) -> Option<&Command<'a>> {
  30.         self.commands.get(name)
  31.     }
  32.  
  33.     pub fn run(&self, input: &str) -> Result<(), CommandParseError> {
  34.         let parsed_syntax_res = parsing::parse(self, input);
  35.  
  36.         if parsed_syntax_res.is_err() {
  37.             return Err(parsed_syntax_res.err().unwrap());
  38.         }
  39.  
  40.         let parsed_syntax = parsed_syntax_res.ok().unwrap();
  41.  
  42.         parsed_syntax.branch.execute(parsed_syntax.parameters);
  43.         Ok(())
  44.     }
  45. }
  46.  
  47. pub enum ParameterVal {
  48.     Raw(String),
  49.     Number(i32),
  50.     Multi(Vec<Parameter>),
  51. }
  52.  
  53. pub struct Parameter {
  54.     pub val: ParameterVal,
  55. }
  56.  
  57. #[derive(PartialEq, Clone)]
  58. pub enum ParameterKind {
  59.     Raw,
  60.     Number,
  61.     List(Box<ParameterKind>),
  62.     None,
  63. }
  64.  
  65. impl std::fmt::Display for ParameterKind {
  66.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  67.         let name = match self {
  68.             ParameterKind::Raw => "raw",
  69.             ParameterKind::Number => "number",
  70.             ParameterKind::List(_) => "list",
  71.             _ => "unknown",
  72.         };
  73.         f.write_str(name)
  74.     }
  75. }
  76.  
  77. pub enum CommandParseError {
  78.     InvalidInput,
  79.     UnknownCommand,
  80.     InvalidBranch,
  81.     MissingParameter(ParameterKind),
  82.     InvalidParameter(String),
  83. }
  84.  
  85. pub struct Command<'a> {
  86.     pub name: &'a str,
  87.     pub branches: Vec<Branch<'a>>,
  88.     default_branch: Option<Branch<'a>>,
  89. }
  90.  
  91. impl<'a> Command<'a> {
  92.     pub fn new(name: &'a str) -> Self {
  93.         Command {
  94.             name,
  95.             branches: Vec::new(),
  96.             default_branch: Option::None,
  97.         }
  98.     }
  99.  
  100.     pub fn new_branched(name: &'a str, branches: Vec<Branch<'a>>) -> Result<Self, String> {
  101.         let mut default_branch = Option::None;
  102.         let mut branches = Vec::from(branches);
  103.  
  104.         if branches.len() == 1 {
  105.             default_branch = Option::Some(branches.swap_remove(0));
  106.         } else {
  107.             let mut idx = 0;
  108.             while idx < branches.len() {
  109.                 unsafe {
  110.                     if !branches.get_unchecked(idx).aliases.is_empty() {
  111.                         idx += 1;
  112.                         continue;
  113.                     }
  114.                 }
  115.  
  116.                 idx += 1;
  117.  
  118.                 if default_branch.is_some() {
  119.                     return Result::Err("default branch already set".to_owned());
  120.                 } else {
  121.                     default_branch = Option::Some(branches.swap_remove(idx));
  122.                     break;
  123.                 }
  124.             }
  125.         }
  126.  
  127.         Result::Ok(Self {
  128.             name,
  129.             branches,
  130.             default_branch,
  131.         })
  132.     }
  133.  
  134.     pub fn new_single(name: &'a str, default_branch: Branch<'a>) -> Self {
  135.         Self {
  136.             name,
  137.             branches: Vec::new(),
  138.             default_branch: Option::Some(default_branch),
  139.         }
  140.     }
  141.  
  142.     pub fn add_branch(&mut self, branch: Branch<'a>) -> Result<(), String> {
  143.         if branch.aliases.is_empty() {
  144.             if self.default_branch.is_some() {
  145.                 return Result::Err("default branch already set".to_owned());
  146.             } else {
  147.                 self.default_branch = Option::Some(branch);
  148.             }
  149.         } else {
  150.             self.branches.push(branch);
  151.         }
  152.  
  153.         Result::Ok(())
  154.     }
  155. }
  156.  
  157. pub struct Branch<'a> {
  158.     aliases: Vec<&'a str>,
  159.     param_types: Vec<ParameterKind>,
  160.     task: Box<dyn FnMut(&mut Iter<Parameter>)>,
  161. }
  162.  
  163. impl<'a> Branch<'a> {
  164.     pub fn new<F: FnMut(&mut Iter<Parameter>) + 'static>(
  165.         aliases: Vec<&'a str>,
  166.         param_format: &'a str,
  167.         task: F,
  168.     ) -> Self {
  169.         Self {
  170.             aliases,
  171.             param_types: parsing::parse_param_types(param_format),
  172.             task: Box::new(task),
  173.         }
  174.     }
  175.  
  176.     pub fn default<F: FnMut(&mut Iter<Parameter>) + 'static>(param_format: &'a str, task: F) -> Self {
  177.         Self::new(Vec::new(), param_format, task)
  178.     }
  179.  
  180.     fn execute(&mut self, params: Vec<Parameter>) {
  181.         (self.task)(&mut params.iter())
  182.     }
  183. }
  184.  
  185. pub trait ParamValueShortcut {
  186.     fn as_str(&self) -> &String;
  187.  
  188.     fn as_i32(&self) -> &i32;
  189.  
  190.     fn as_multi(&self) -> &Vec<Parameter>;
  191. }
  192.  
  193. impl ParamValueShortcut for Parameter {
  194.     fn as_str(&self) -> &String {
  195.         match &self.val {
  196.             ParameterVal::Raw(v) => v,
  197.             _ => panic!(),
  198.         }
  199.     }
  200.  
  201.     fn as_i32(&self) -> &i32 {
  202.         match &self.val {
  203.             ParameterVal::Number(v) => v,
  204.             _ => panic!(),
  205.         }
  206.     }
  207.  
  208.     fn as_multi(&self) -> &Vec<Parameter> {
  209.         match &self.val {
  210.             ParameterVal::Multi(v) => v,
  211.             _ => panic!(),
  212.         }
  213.     }
  214. }
  215.  
  216. pub trait ParamAccessor {
  217.     fn poll(&mut self) -> &Parameter;
  218.  
  219.     fn poll_str(&mut self) -> &String;
  220.  
  221.     fn poll_i32(&mut self) -> &i32;
  222.  
  223.     fn poll_multi(&mut self) -> &Vec<Parameter>;
  224.  
  225.     fn poll_multi_as<B, F: FnMut(&Parameter) -> B>(&mut self, map_func: F) -> Vec<B>;
  226. }
  227.  
  228. impl<'a> ParamAccessor for Iter<'a, Parameter> {
  229.     fn poll(&mut self) -> &Parameter {
  230.         self.next().unwrap()
  231.     }
  232.  
  233.     fn poll_str(&mut self) -> &String {
  234.         self.poll().as_str()
  235.     }
  236.  
  237.     fn poll_i32(&mut self) -> &i32 {
  238.         self.poll().as_i32()
  239.     }
  240.  
  241.     fn poll_multi(&mut self) -> &Vec<Parameter> {
  242.         self.poll().as_multi()
  243.     }
  244.  
  245.     fn poll_multi_as<B, F>(&mut self, map_func: F) -> Vec<B>
  246.     where
  247.         F: FnMut(&Parameter) -> B,
  248.     {
  249.         self.poll_multi().iter().map(map_func).collect()
  250.     }
  251. }
  252.  
  253. mod parsing {
  254.     use super::*;
  255.  
  256.     pub struct SyntaxTree<'a> {
  257.         pub command: &'a Command<'a>,
  258.         pub branch: &'a mut Branch<'a>,
  259.         pub parameters: Vec<Parameter>,
  260.     }
  261.  
  262.     pub fn parse<'a>(
  263.         command_line: &'a CommandLine<'a>,
  264.         input: &'a str,
  265.     ) -> Result<SyntaxTree<'a>, CommandParseError> {
  266.         let mut parts = parse_input_parts(input).into_iter();
  267.         let command_name_res = parts.next();
  268.  
  269.         if command_name_res.is_none() {
  270.             return Err(CommandParseError::InvalidInput);
  271.         }
  272.  
  273.         let command_name = command_name_res.unwrap();
  274.         let command_res = command_line.lookup(command_name.as_str());
  275.  
  276.         if command_res.is_none() {
  277.             return Err(CommandParseError::UnknownCommand);
  278.         }
  279.  
  280.         let command = command_res.unwrap();
  281.         let mut peekable_parts = parts.peekable();
  282.         let possible_branch_name_res = peekable_parts.peek().cloned();
  283.  
  284.         if possible_branch_name_res.is_none() {
  285.             return Err(CommandParseError::InvalidInput);
  286.         }
  287.  
  288.         let possible_branch_name = possible_branch_name_res.unwrap().clone();
  289.         let selected_branch = command.default_branch.as_ref().or_else(|| {
  290.             for branch in &command.branches {
  291.                 if branch.aliases.contains(&possible_branch_name.as_str()) {
  292.                     peekable_parts.next(); // take non-default branch name from the input parts
  293.                     return Some(branch);
  294.                 }
  295.             }
  296.  
  297.             return None;
  298.         });
  299.  
  300.         if selected_branch.is_none() {
  301.             return Err(CommandParseError::InvalidBranch);
  302.         }
  303.  
  304.         let selected_branch = selected_branch.unwrap();
  305.         let mut parameters: Vec<Parameter> = Vec::new();
  306.  
  307.         for param_type in selected_branch.param_types.iter() {
  308.             let raw_param_res = peekable_parts.next();
  309.  
  310.             if raw_param_res.is_none() {
  311.                 return Err(CommandParseError::MissingParameter(param_type.clone()));
  312.             }
  313.  
  314.             let raw_param = raw_param_res.unwrap();
  315.             let result = parse_param(raw_param.clone(), &param_type);
  316.  
  317.             if result.is_none() {
  318.                 return Err(CommandParseError::InvalidParameter(raw_param.to_owned()));
  319.             }
  320.  
  321.             parameters.push(result.unwrap());
  322.         }
  323.  
  324.         return Ok(SyntaxTree {
  325.             command,
  326.             branch: selected_branch,
  327.             parameters,
  328.         });
  329.     }
  330.  
  331.     pub fn parse_param_types(format: &str) -> Vec<ParameterKind> {
  332.         let mut result = Vec::new();
  333.  
  334.         let mut chars_peek = format.chars().peekable();
  335.         let iter = format.chars();
  336.         let mut prev_param_was_list = false;
  337.  
  338.         for c in iter {
  339.             chars_peek.next();
  340.  
  341.             if prev_param_was_list {
  342.                 prev_param_was_list = false;
  343.                 continue;
  344.             }
  345.  
  346.             let kind = match c {
  347.                 's' => ParameterKind::Raw,
  348.                 'n' => ParameterKind::Number,
  349.                 _ => ParameterKind::None,
  350.             };
  351.  
  352.             let check_param_res = check_list_param_or(&mut chars_peek, kind);
  353.  
  354.             if check_param_res.0 {
  355.                 prev_param_was_list = true;
  356.             }
  357.  
  358.             let kind = check_param_res.1;
  359.  
  360.             if kind != ParameterKind::None {
  361.                 result.push(kind);
  362.             }
  363.         }
  364.  
  365.         return result;
  366.     }
  367.  
  368.     pub fn check_list_param_or(
  369.         chars: &mut Peekable<Chars>,
  370.         original_type: ParameterKind,
  371.     ) -> (bool, ParameterKind) {
  372.         let mut c = chars.clone();
  373.         let next_char_res = c.peek();
  374.  
  375.         if next_char_res.is_some() {
  376.             let next_char = *next_char_res.unwrap();
  377.  
  378.             if next_char == '{' || next_char == '[' {
  379.                 chars.next().unwrap();
  380.                 return (true, ParameterKind::List(Box::new(original_type)));
  381.             }
  382.         }
  383.  
  384.         return (false, original_type);
  385.     }
  386.  
  387.     fn parse_input_parts(input: &str) -> Vec<String> {
  388.         let mut parts = Vec::new();
  389.         let mut curr_part = String::new();
  390.         let mut in_compound_param = false;
  391.         let mut last_char = std::char::MAX;
  392.  
  393.         for (i, c) in input.chars().enumerate() {
  394.             match c {
  395.                 '[' | '{' => {
  396.                     if last_char == '\\' {
  397.                         curr_part.pop();
  398.                         curr_part.push(c);
  399.                         continue;
  400.                     }
  401.  
  402.                     curr_part.push(c);
  403.                     in_compound_param = true;
  404.                 }
  405.                 ']' | '}' => {
  406.                     if last_char == '\\' {
  407.                         curr_part.pop();
  408.                         curr_part.push(c);
  409.                         continue;
  410.                     }
  411.  
  412.                     if in_compound_param {
  413.                         curr_part.push(c);
  414.                         parts.push(curr_part.to_owned());
  415.                         curr_part.clear();
  416.                         in_compound_param = false;
  417.                     }
  418.                 }
  419.                 '"' => {
  420.                     if last_char == '\\' {
  421.                         curr_part.pop();
  422.                         curr_part.push(c);
  423.                         continue;
  424.                     }
  425.  
  426.                     in_compound_param = !in_compound_param;
  427.  
  428.                     if !in_compound_param {
  429.                         parts.push(curr_part.to_owned());
  430.                         curr_part.clear();
  431.                     }
  432.                 }
  433.                 ' ' => {
  434.                     if in_compound_param || last_char == '\\' {
  435.                         curr_part.push(c);
  436.                     } else {
  437.                         if last_char != '"' {
  438.                             parts.push(curr_part.to_owned());
  439.                             curr_part.clear();
  440.                         }
  441.                     }
  442.                 }
  443.                 _ => {
  444.                     curr_part.push(c);
  445.                 }
  446.             }
  447.  
  448.             if i + 1 == input.len() {
  449.                 parts.push(curr_part.to_owned());
  450.                 break;
  451.             }
  452.  
  453.             last_char = c;
  454.         }
  455.  
  456.         parts
  457.     }
  458.  
  459.     fn parse_param(raw_param: String, param_type: &ParameterKind) -> Option<Parameter> {
  460.         match param_type {
  461.             ParameterKind::Raw => {
  462.                 return Some(Parameter {
  463.                     val: ParameterVal::Raw(raw_param),
  464.                 });
  465.             }
  466.             ParameterKind::Number => {
  467.                 let num_parse_res = raw_param.parse::<i32>();
  468.  
  469.                 if num_parse_res.is_err() {
  470.                     return None;
  471.                 }
  472.  
  473.                 return Some(Parameter {
  474.                     val: ParameterVal::Number(num_parse_res.unwrap()),
  475.                 });
  476.             }
  477.             ParameterKind::List(t) => {
  478.                 const ELEMENT_DELIMITER: char = ',';
  479.  
  480.                 let mut chars = raw_param.chars();
  481.                 let open_char = chars.next().unwrap();
  482.  
  483.                 if open_char != '{' && open_char != '[' {
  484.                     return None;
  485.                 }
  486.  
  487.                 let close_char = chars.next_back().unwrap();
  488.  
  489.                 if close_char != '}' && close_char != ']' {
  490.                     return None;
  491.                 }
  492.  
  493.                 let raw_param = chars.as_str();
  494.                 let raw_elements: Vec<&str> = raw_param.split(ELEMENT_DELIMITER).collect();
  495.                 let mut elements: Vec<Parameter> = Vec::new();
  496.  
  497.                 for e in raw_elements {
  498.                     let e = e.trim();
  499.                     let res = parse_param(e.to_string(), t);
  500.  
  501.                     if res.is_none() {
  502.                         return None;
  503.                     }
  504.  
  505.                     elements.push(res.unwrap());
  506.                 }
  507.  
  508.                 return Some(Parameter {
  509.                     val: ParameterVal::Multi(elements),
  510.                 });
  511.             }
  512.             _ => {}
  513.         };
  514.  
  515.         return None;
  516.     }
  517. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top