From b32311ae65e392b99b964befb8fcfdc41cd4e7cc Mon Sep 17 00:00:00 2001 From: Joel Wachsler Date: Sun, 17 Jul 2022 12:19:22 +0000 Subject: [PATCH] Extract table logic --- .../src/md_parser/md_token.rs | 129 +++++++++++------- 1 file changed, 83 insertions(+), 46 deletions(-) diff --git a/qbittorrent-web-api-gen/src/md_parser/md_token.rs b/qbittorrent-web-api-gen/src/md_parser/md_token.rs index 139c898..23bca7b 100644 --- a/qbittorrent-web-api-gen/src/md_parser/md_token.rs +++ b/qbittorrent-web-api-gen/src/md_parser/md_token.rs @@ -78,58 +78,18 @@ impl MdToken { pub fn from(content: &str) -> Vec { // to prevent infinite loops - let mut max_iterations = 10000; - let mut decrease_max_iterations = || { - max_iterations -= 1; - if max_iterations <= 0 { - panic!("Max iterations reached, missing termination?"); - }; - }; + let mut max_iterator_checker = MaxIteratorChecker::default(); let mut output = Vec::new(); - let mut iter = content.lines().peekable(); + while let Some(line) = iter.next() { - decrease_max_iterations(); + max_iterator_checker.decrease(); - // assume this is a table + // assume that lines starting with "|" are tables if line.contains('|') { - let to_columns = |column_line: &str| { - column_line - .replace('`', "") - .split('|') - .map(|s| s.trim().to_string()) - .collect() - }; - - let table_header = TableRow { - raw: line.into(), - columns: to_columns(line), - }; - let table_split = iter.next().unwrap(); - let mut table_rows = Vec::new(); - while let Some(peeked_row_line) = iter.peek() { - decrease_max_iterations(); - - if !peeked_row_line.contains('|') { - // we've reached the end of the table, let's go back one step - break; - } - - let next_row_line = iter.next().unwrap(); - let table_row = TableRow { - raw: next_row_line.to_string(), - columns: to_columns(next_row_line), - }; - - table_rows.push(table_row); - } - - output.push(MdToken::Content(MdContent::Table(Table { - header: table_header, - split: table_split.to_string(), - rows: table_rows, - }))); + let table = TableParser::new(&mut max_iterator_checker, &mut iter).parse(line); + output.push(MdToken::Content(table)); } else { output.push(MdToken::parse_token(line)); } @@ -138,3 +98,80 @@ impl MdToken { output } } + +struct TableParser<'a, 'b> { + max_iterator_checker: &'a mut MaxIteratorChecker, + iter: &'a mut std::iter::Peekable>, +} + +impl<'a, 'b> TableParser<'a, 'b> { + fn new( + max_iterator_checker: &'a mut MaxIteratorChecker, + iter: &'a mut std::iter::Peekable>, + ) -> Self { + Self { + max_iterator_checker, + iter, + } + } + + fn parse(&mut self, line: &str) -> MdContent { + let to_columns = |column_line: &str| { + column_line + .replace('`', "") + .split('|') + .map(|s| s.trim().to_string()) + .collect() + }; + + let table_header = TableRow { + raw: line.into(), + columns: to_columns(line), + }; + + let table_split = self.iter.next().unwrap(); + let mut table_rows = Vec::new(); + while let Some(peeked_row_line) = self.iter.peek() { + self.max_iterator_checker.decrease(); + + if !peeked_row_line.contains('|') { + // we've reached the end of the table, let's go back one step + break; + } + + let next_row_line = self.iter.next().unwrap(); + table_rows.push(TableRow { + raw: next_row_line.to_string(), + columns: to_columns(next_row_line), + }); + } + + MdContent::Table(Table { + header: table_header, + split: table_split.to_string(), + rows: table_rows, + }) + } +} + +#[derive(Debug)] +struct MaxIteratorChecker { + max_iterations: i32, +} + +impl MaxIteratorChecker { + fn decrease(&mut self) { + self.max_iterations -= 1; + if self.max_iterations <= 0 { + panic!("Max iterations reached, missing termination?"); + } + } +} + +impl Default for MaxIteratorChecker { + fn default() -> Self { + MaxIteratorChecker { + max_iterations: 10000, + } + } +}