Advertisement
Guest User

Untitled

a guest
May 19th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.73 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement