From 2f21280db96e9c8086e123f756f5cad27cbfa0bf Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Thu, 13 Oct 2022 18:14:23 +0200 Subject: Refactor some code to improve coverage --- src/parser.rs | 32 +++++++++++++------------------- src/subtokenize.rs | 25 +++++++++++-------------- src/to_html.rs | 42 ++++++++++++++++++------------------------ src/to_mdast.rs | 20 ++++++-------------- src/tokenizer.rs | 28 ++++++++++++++-------------- 5 files changed, 62 insertions(+), 85 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index a7962d0..4e8d859 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -47,15 +47,13 @@ pub fn parse<'a>( gfm_footnote_definitions: vec![], }; - let mut tokenizer = Tokenizer::new( - Point { - line: 1, - column: 1, - index: 0, - vs: 0, - }, - &parse_state, - ); + let start = Point { + line: 1, + column: 1, + index: 0, + vs: 0, + }; + let mut tokenizer = Tokenizer::new(start, &parse_state); let state = tokenizer.push( (0, 0), @@ -65,21 +63,17 @@ pub fn parse<'a>( let mut result = tokenizer.flush(state, true)?; let mut events = tokenizer.events; - parse_state - .gfm_footnote_definitions - .append(&mut result.gfm_footnote_definitions); - parse_state.definitions.append(&mut result.definitions); - loop { - let mut result = subtokenize(&mut events, &parse_state, &None)?; - parse_state - .gfm_footnote_definitions - .append(&mut result.gfm_footnote_definitions); - parse_state.definitions.append(&mut result.definitions); + let fn_defs = &mut parse_state.gfm_footnote_definitions; + let defs = &mut parse_state.definitions; + fn_defs.append(&mut result.gfm_footnote_definitions); + defs.append(&mut result.definitions); if result.done { break; } + + result = subtokenize(&mut events, &parse_state, &None)?; } Ok((events, parse_state)) diff --git a/src/subtokenize.rs b/src/subtokenize.rs index 7b8b80a..9c049b2 100644 --- a/src/subtokenize.rs +++ b/src/subtokenize.rs @@ -45,16 +45,14 @@ pub fn link_to(events: &mut [Event], previous: usize, next: usize) { debug_assert_eq!(events[previous].kind, Kind::Enter); debug_assert!( VOID_EVENTS.iter().any(|d| d == &events[previous].name), - "expected `{:?}` to be void", - events[previous].name + "expected event to be void" ); debug_assert_eq!(events[previous + 1].kind, Kind::Exit); debug_assert_eq!(events[previous].name, events[previous + 1].name); debug_assert_eq!(events[next].kind, Kind::Enter); debug_assert!( VOID_EVENTS.iter().any(|d| d == &events[next].name), - "expected `{:?}` to be void", - events[next].name + "expected event to be void" ); // Note: the exit of this event may not exist, so don’t check for that. @@ -105,12 +103,15 @@ pub fn subtokenize( let mut link_index = Some(index); // Subtokenizer. let mut tokenizer = Tokenizer::new(event.point.clone(), parse_state); + debug_assert!( + !matches!(link.content, Content::Flow), + "cannot use flow as subcontent yet" + ); // Substate. let mut state = State::Next(match link.content { - Content::Flow => unreachable!("flow subcontent not implemented yet"), Content::Content => StateName::ContentDefinitionBefore, Content::String => StateName::StringStart, - Content::Text => StateName::TextStart, + _ => StateName::TextStart, }); // Check if this is the first paragraph, after zero or more @@ -262,15 +263,11 @@ pub fn divide_events( while index > 0 { index -= 1; - map.add( - slices[index].0, - if slices[index].0 == events.len() { - 0 - } else { - 2 - }, - child_events.split_off(slices[index].1), + debug_assert!( + slices[index].0 < events.len(), + "expected slice start in bounds" ); + map.add(slices[index].0, 2, child_events.split_off(slices[index].1)); } (acc_before.0 + (slices.len() * 2), acc_before.1 + len) diff --git a/src/to_html.rs b/src/to_html.rs index b4264c3..ab55376 100644 --- a/src/to_html.rs +++ b/src/to_html.rs @@ -180,10 +180,9 @@ impl<'a> CompileContext<'a> { /// Push a str to the last buffer. fn push(&mut self, value: &str) { - self.buffers - .last_mut() - .expect("Cannot push w/o buffer") - .push_str(value); + let last_buf_opt = self.buffers.last_mut(); + let last_buf = last_buf_opt.expect("at least one buffer should exist"); + last_buf.push_str(value); } /// Add a line ending. @@ -194,14 +193,11 @@ impl<'a> CompileContext<'a> { /// Add a line ending if needed (as in, there’s no eol/eof already). fn line_ending_if_needed(&mut self) { - let tail = self - .buffers - .last() - .expect("at least one buffer should exist") - .as_bytes() - .last(); - - if !matches!(tail, None | Some(b'\n' | b'\r')) { + let last_buf_opt = self.buffers.last(); + let last_buf = last_buf_opt.expect("at least one buffer should exist"); + let last_byte = last_buf.as_bytes().last(); + + if !matches!(last_byte, None | Some(b'\n' | b'\r')) { self.line_ending(); } } @@ -805,11 +801,9 @@ fn on_exit_raw_flow_chunk(context: &mut CompileContext) { /// Handle [`Exit`][Kind::Exit]:{[`CodeFencedFence`][Name::CodeFencedFence],[`MathFlowFence`][Name::MathFlowFence]}. fn on_exit_raw_flow_fence(context: &mut CompileContext) { - let count = if let Some(count) = context.raw_flow_fences_count { - count - } else { - 0 - }; + let count = context + .raw_flow_fences_count + .expect("expected `raw_flow_fences_count`"); if count == 0 { context.push(">"); @@ -1432,18 +1426,18 @@ fn on_exit_media(context: &mut CompileContext) { }); let definition_index = if media.destination.is_none() { - id.and_then(|id| { + id.map(|id| { let mut index = 0; - while index < context.definitions.len() { - if context.definitions[index].id == id { - return Some(index); - } - + while index < context.definitions.len() && context.definitions[index].id != id { index += 1; } - None + debug_assert!( + index < context.definitions.len(), + "expected defined definition" + ); + index }) } else { None diff --git a/src/to_mdast.rs b/src/to_mdast.rs index 39f6bc5..1d25beb 100644 --- a/src/to_mdast.rs +++ b/src/to_mdast.rs @@ -208,22 +208,14 @@ impl<'a> CompileContext<'a> { let end = point_from_event(ev); let (tree, stack, event_stack) = self.trees.last_mut().expect("Cannot get tail w/o tree"); let node = delve_mut(tree, stack); - node.position_mut() - .expect("Cannot pop manually added node") - .end = end; + let pos = node.position_mut().expect("Cannot pop manually added node"); + pos.end = end; stack.pop().unwrap(); - - if let Some(left_index) = event_stack.pop() { - let left = &self.events[left_index]; - if left.name != ev.name { - on_mismatch_error(self, Some(ev), left)?; - } - } else { - return Err(format!( - "{}:{}: Cannot close `{:?}`, it’s not open", - ev.point.line, ev.point.column, ev.name - )); + let left_index = event_stack.pop().unwrap(); + let left = &self.events[left_index]; + if left.name != ev.name { + on_mismatch_error(self, Some(ev), left)?; } Ok(()) diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 84d3d6d..346e04e 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -521,9 +521,7 @@ impl<'a> Tokenizer<'a> { if VOID_EVENTS.iter().any(|d| d == &name) { debug_assert!( current == previous.name, - "expected event to be void (`{:?}`), instead of including `{:?}`", - current, - previous.name + "expected event to be void, instead of including something" ); } @@ -536,12 +534,13 @@ impl<'a> Tokenizer<'a> { } log::debug!("exit: `{:?}`", name); - self.events.push(Event { + let event = Event { kind: Kind::Exit, name, point, link: None, - }); + }; + self.events.push(event); } /// Capture the tokenizer progress. @@ -579,13 +578,13 @@ impl<'a> Tokenizer<'a> { // No need to capture (and restore) when `nok` is `State::Nok`, because the // parent attempt will do it. let progress = Some(self.capture()); - - self.attempts.push(Attempt { + let attempt = Attempt { kind: AttemptKind::Check, progress, ok, nok, - }); + }; + self.attempts.push(attempt); } /// Stack an attempt, moving to `ok` on [`State::Ok`][] and `nok` on @@ -600,12 +599,13 @@ impl<'a> Tokenizer<'a> { Some(self.capture()) }; - self.attempts.push(Attempt { + let attempt = Attempt { kind: AttemptKind::Attempt, progress, ok, nok, - }); + }; + self.attempts.push(attempt); } /// Tokenize. @@ -629,12 +629,12 @@ impl<'a> Tokenizer<'a> { if resolve { let resolvers = self.resolvers.split_off(0); let mut index = 0; + let defs = &mut value.definitions; + let fn_defs = &mut value.gfm_footnote_definitions; while index < resolvers.len() { if let Some(mut result) = call_resolve(self, resolvers[index])? { - value - .gfm_footnote_definitions - .append(&mut result.gfm_footnote_definitions); - value.definitions.append(&mut result.definitions); + fn_defs.append(&mut result.gfm_footnote_definitions); + defs.append(&mut result.definitions); } index += 1; } -- cgit