diff options
40 files changed, 687 insertions, 922 deletions
@@ -26,14 +26,14 @@ async fn commonmark() { let re = Regex::new(r"(?m)(?:^`{32} example\n[\s\S]*?\n`{32}$|^#{1,6} *(.*)$)").unwrap(); let re_heading_prefix = Regex::new(r"#{1,6} ").unwrap(); let re_in_out = Regex::new(r"\n\.(?:\n|$)").unwrap(); - let mut current_heading: Option<String> = None; + let mut current_heading = None; let mut number = 1; let value = Regex::new(r"<!-- END TESTS -->[\s\S]*") .unwrap() .replace(&value, ""); let value = Regex::new(r"→").unwrap().replace_all(&value, "\t"); - let mut cases: Vec<String> = vec![]; + let mut cases = vec![]; for mat in re.find_iter(&value) { let mut lines = mat.as_str().lines().collect::<Vec<_>>(); diff --git a/src/compiler.rs b/src/compiler.rs index 1723190..a575221 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -201,7 +201,7 @@ impl<'a> CompileContext<'a> { #[allow(clippy::too_many_lines)] pub fn compile(events: &[Event], codes: &[Code], options: &Options) -> String { let mut index = 0; - let mut line_ending_inferred: Option<LineEnding> = None; + let mut line_ending_inferred = None; // First, we figure out what the used line ending style is. // Stop when we find a line ending. @@ -240,7 +240,7 @@ pub fn compile(events: &[Event], codes: &[Code], options: &Options) -> String { }; let mut context = CompileContext::new(events, codes, options, line_ending_default); - let mut definition_indices: Vec<(usize, usize)> = vec![]; + let mut definition_indices = vec![]; let mut index = 0; let mut definition_inside = false; @@ -1041,7 +1041,7 @@ fn on_exit_media(context: &mut CompileContext) { .or(media.label_id) .map(|id| normalize_identifier(&id)); let label = media.label.unwrap(); - let mut definition: Option<&Definition> = None; + let mut definition = None; if let Some(id) = id { let mut index = 0; diff --git a/src/construct/attention.rs b/src/construct/attention.rs index 42c0965..b4265f0 100644 --- a/src/construct/attention.rs +++ b/src/construct/attention.rs @@ -52,7 +52,7 @@ //! [html-strong]: https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-strong-element use crate::token::Token; -use crate::tokenizer::{Code, Event, EventType, Point, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, Event, EventType, Point, State, Tokenizer}; use crate::unicode::PUNCTUATION; use crate::util::edit_map::EditMap; @@ -169,13 +169,13 @@ struct Sequence { /// > | ** /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('*' | '_') if tokenizer.parse_state.constructs.attention => { tokenizer.enter(Token::AttentionSequence); inside(tokenizer, code, MarkerKind::from_code(code)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -185,16 +185,16 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | ** /// ^^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code, marker: MarkerKind) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code, marker: MarkerKind) -> State { match code { Code::Char(char) if char == marker.as_char() => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| inside(t, c, marker))), 0) + State::Fn(Box::new(move |t, c| inside(t, c, marker))) } _ => { tokenizer.exit(Token::AttentionSequence); tokenizer.register_resolver("attention".to_string(), Box::new(resolve_attention)); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } } @@ -205,7 +205,7 @@ fn resolve_attention(tokenizer: &mut Tokenizer, map: &mut EditMap) -> bool { let codes = &tokenizer.parse_state.codes; let mut start = 0; let mut balance = 0; - let mut sequences: Vec<Sequence> = vec![]; + let mut sequences = vec![]; // Find sequences of sequences and information about them. while start < tokenizer.events.len() { diff --git a/src/construct/autolink.rs b/src/construct/autolink.rs index e8caf3b..606fc9b 100644 --- a/src/construct/autolink.rs +++ b/src/construct/autolink.rs @@ -103,7 +103,7 @@ use crate::constant::{AUTOLINK_DOMAIN_SIZE_MAX, AUTOLINK_SCHEME_SIZE_MAX}; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of an autolink. /// @@ -113,7 +113,7 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | a<user@example.com>b /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('<') if tokenizer.parse_state.constructs.autolink => { tokenizer.enter(Token::Autolink); @@ -121,9 +121,9 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.consume(code); tokenizer.exit(Token::AutolinkMarker); tokenizer.enter(Token::AutolinkProtocol); - (State::Fn(Box::new(open)), 0) + State::Fn(Box::new(open)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -135,14 +135,14 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a<user@example.com>b /// ^ /// ``` -fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(char) if char.is_ascii_alphabetic() => { tokenizer.consume(code); - (State::Fn(Box::new(scheme_or_email_atext)), 0) + State::Fn(Box::new(scheme_or_email_atext)) } Code::Char(char) if is_ascii_atext(char) => email_atext(tokenizer, code), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -154,7 +154,7 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a<user@example.com>b /// ^ /// ``` -fn scheme_or_email_atext(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn scheme_or_email_atext(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('+' | '-' | '.' | '0'..='9' | 'A'..='Z' | 'a'..='z') => { scheme_inside_or_email_atext(tokenizer, code, 1) @@ -171,26 +171,19 @@ fn scheme_or_email_atext(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult /// > | a<user@example.com>b /// ^ /// ``` -fn scheme_inside_or_email_atext( - tokenizer: &mut Tokenizer, - code: Code, - size: usize, -) -> StateFnResult { +fn scheme_inside_or_email_atext(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char(':') => { tokenizer.consume(code); - (State::Fn(Box::new(url_inside)), 0) + State::Fn(Box::new(url_inside)) } Code::Char('+' | '-' | '.' | '0'..='9' | 'A'..='Z' | 'a'..='z') if size < AUTOLINK_SCHEME_SIZE_MAX => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| { - scheme_inside_or_email_atext(t, c, size + 1) - })), - 0, - ) + State::Fn(Box::new(move |t, c| { + scheme_inside_or_email_atext(t, c, size + 1) + })) } _ => email_atext(tokenizer, code), } @@ -202,19 +195,19 @@ fn scheme_inside_or_email_atext( /// > | a<https://example.com>b /// ^ /// ``` -fn url_inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn url_inside(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => { tokenizer.exit(Token::AutolinkProtocol); end(tokenizer, code) } - Code::Char(char) if char.is_ascii_control() => (State::Nok, 0), + Code::Char(char) if char.is_ascii_control() => State::Nok, Code::None | Code::CarriageReturnLineFeed | Code::VirtualSpace | Code::Char(' ') => { - (State::Nok, 0) + State::Nok } Code::Char(_) => { tokenizer.consume(code); - (State::Fn(Box::new(url_inside)), 0) + State::Fn(Box::new(url_inside)) } } } @@ -225,17 +218,17 @@ fn url_inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a<user.name@example.com>b /// ^ /// ``` -fn email_atext(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn email_atext(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('@') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| email_at_sign_or_dot(t, c, 0))), 0) + State::Fn(Box::new(|t, c| email_at_sign_or_dot(t, c, 0))) } Code::Char(char) if is_ascii_atext(char) => { tokenizer.consume(code); - (State::Fn(Box::new(email_atext)), 0) + State::Fn(Box::new(email_atext)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -245,10 +238,10 @@ fn email_atext(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a<user.name@example.com>b /// ^ ^ /// ``` -fn email_at_sign_or_dot(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn email_at_sign_or_dot(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char(char) if char.is_ascii_alphanumeric() => email_value(tokenizer, code, size), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -258,11 +251,11 @@ fn email_at_sign_or_dot(tokenizer: &mut Tokenizer, code: Code, size: usize) -> S /// > | a<user.name@example.com>b /// ^ /// ``` -fn email_label(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn email_label(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char('.') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| email_at_sign_or_dot(t, c, 0))), 0) + State::Fn(Box::new(|t, c| email_at_sign_or_dot(t, c, 0))) } Code::Char('>') => { let index = tokenizer.events.len(); @@ -284,23 +277,17 @@ fn email_label(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnRes /// > | a<user.name@ex-ample.com>b /// ^ /// ``` -fn email_value(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn email_value(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char('-') if size < AUTOLINK_DOMAIN_SIZE_MAX => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| email_value(t, c, size + 1))), - 0, - ) + State::Fn(Box::new(move |t, c| email_value(t, c, size + 1))) } Code::Char(char) if char.is_ascii_alphanumeric() && size < AUTOLINK_DOMAIN_SIZE_MAX => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| email_label(t, c, size + 1))), - 0, - ) + State::Fn(Box::new(move |t, c| email_label(t, c, size + 1))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -312,14 +299,14 @@ fn email_value(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnRes /// > | a<user@example.com>b /// ^ /// ``` -fn end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn end(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => { tokenizer.enter(Token::AutolinkMarker); tokenizer.consume(code); tokenizer.exit(Token::AutolinkMarker); tokenizer.exit(Token::Autolink); - (State::Ok, 0) + State::Ok(0) } _ => unreachable!("expected `>`"), } diff --git a/src/construct/blank_line.rs b/src/construct/blank_line.rs index 5b6513d..1121b81 100644 --- a/src/construct/blank_line.rs +++ b/src/construct/blank_line.rs @@ -33,7 +33,7 @@ //! [flow]: crate::content::flow use crate::construct::partial_space_or_tab::space_or_tab; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of a blank line. /// @@ -45,7 +45,7 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab(), after)(tokenizer, code) } @@ -57,11 +57,11 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | /// ^ /// ``` -fn after(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(_tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/block_quote.rs b/src/construct/block_quote.rs index d1b4005..da21add 100644 --- a/src/construct/block_quote.rs +++ b/src/construct/block_quote.rs @@ -36,7 +36,7 @@ use crate::constant::TAB_SIZE; use crate::construct::partial_space_or_tab::space_or_tab_min_max; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of block quote. /// @@ -44,7 +44,7 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | > a /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -53,7 +53,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { if tokenizer.parse_state.constructs.block_quote { tokenizer.go(space_or_tab_min_max(0, max), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -63,7 +63,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | > a /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => { tokenizer.enter(Token::BlockQuote); @@ -80,7 +80,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | > b /// ^ /// ``` -pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -96,16 +96,16 @@ pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | > b /// ^ /// ``` -fn cont_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn cont_before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => { tokenizer.enter(Token::BlockQuotePrefix); tokenizer.enter(Token::BlockQuoteMarker); tokenizer.consume(code); tokenizer.exit(Token::BlockQuoteMarker); - (State::Fn(Box::new(cont_after)), 0) + State::Fn(Box::new(cont_after)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -117,18 +117,18 @@ fn cont_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | >b /// ^ /// ``` -fn cont_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn cont_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.enter(Token::SpaceOrTab); tokenizer.consume(code); tokenizer.exit(Token::SpaceOrTab); tokenizer.exit(Token::BlockQuotePrefix); - (State::Ok, 0) + State::Ok(0) } _ => { tokenizer.exit(Token::BlockQuotePrefix); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } } diff --git a/src/construct/character_escape.rs b/src/construct/character_escape.rs index eb79486..8403765 100644 --- a/src/construct/character_escape.rs +++ b/src/construct/character_escape.rs @@ -34,7 +34,7 @@ //! [hard_break_escape]: crate::construct::hard_break_escape use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of a character escape. /// @@ -42,16 +42,16 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | a\*b /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('\\') if tokenizer.parse_state.constructs.character_escape => { tokenizer.enter(Token::CharacterEscape); tokenizer.enter(Token::CharacterEscapeMarker); tokenizer.consume(code); tokenizer.exit(Token::CharacterEscapeMarker); - (State::Fn(Box::new(inside)), 0) + State::Fn(Box::new(inside)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -61,15 +61,15 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a\*b /// ^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(char) if char.is_ascii_punctuation() => { tokenizer.enter(Token::CharacterEscapeValue); tokenizer.consume(code); tokenizer.exit(Token::CharacterEscapeValue); tokenizer.exit(Token::CharacterEscape); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/character_reference.rs b/src/construct/character_reference.rs index 2d9d524..b2146e7 100644 --- a/src/construct/character_reference.rs +++ b/src/construct/character_reference.rs @@ -66,7 +66,7 @@ use crate::constant::{ CHARACTER_REFERENCE_HEXADECIMAL_SIZE_MAX, CHARACTER_REFERENCE_NAMED_SIZE_MAX, }; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Kind of a character reference. #[derive(Debug, Clone, PartialEq)] @@ -136,16 +136,16 @@ struct Info { /// > | a	b /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('&') if tokenizer.parse_state.constructs.character_reference => { tokenizer.enter(Token::CharacterReference); tokenizer.enter(Token::CharacterReferenceMarker); tokenizer.consume(code); tokenizer.exit(Token::CharacterReferenceMarker); - (State::Fn(Box::new(open)), 0) + State::Fn(Box::new(open)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -160,7 +160,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a	b /// ^ /// ``` -fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn open(tokenizer: &mut Tokenizer, code: Code) -> State { let info = Info { buffer: String::new(), kind: Kind::Named, @@ -169,7 +169,7 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::CharacterReferenceMarkerNumeric); tokenizer.consume(code); tokenizer.exit(Token::CharacterReferenceMarkerNumeric); - (State::Fn(Box::new(|t, c| numeric(t, c, info))), 0) + State::Fn(Box::new(|t, c| numeric(t, c, info))) } else { tokenizer.enter(Token::CharacterReferenceValue); value(tokenizer, code, info) @@ -185,14 +185,14 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a	b /// ^ /// ``` -fn numeric(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn numeric(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { if let Code::Char('x' | 'X') = code { tokenizer.enter(Token::CharacterReferenceMarkerHexadecimal); tokenizer.consume(code); tokenizer.exit(Token::CharacterReferenceMarkerHexadecimal); tokenizer.enter(Token::CharacterReferenceValue); info.kind = Kind::Hexadecimal; - (State::Fn(Box::new(|t, c| value(t, c, info))), 0) + State::Fn(Box::new(|t, c| value(t, c, info))) } else { tokenizer.enter(Token::CharacterReferenceValue); info.kind = Kind::Decimal; @@ -213,32 +213,32 @@ fn numeric(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResu /// > | a	b /// ^ /// ``` -fn value(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn value(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char(';') if !info.buffer.is_empty() => { let unknown_named = Kind::Named == info.kind && !CHARACTER_REFERENCES.iter().any(|d| d.0 == info.buffer); if unknown_named { - (State::Nok, 0) + State::Nok } else { tokenizer.exit(Token::CharacterReferenceValue); tokenizer.enter(Token::CharacterReferenceMarkerSemi); tokenizer.consume(code); tokenizer.exit(Token::CharacterReferenceMarkerSemi); tokenizer.exit(Token::CharacterReference); - (State::Ok, 0) + State::Ok(0) } } Code::Char(char) => { if info.buffer.len() < info.kind.max() && info.kind.allowed(char) { info.buffer.push(char); tokenizer.consume(code); - (State::Fn(Box::new(|t, c| value(t, c, info))), 0) + State::Fn(Box::new(|t, c| value(t, c, info))) } else { - (State::Nok, 0) + State::Nok } } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/code_fenced.rs b/src/construct/code_fenced.rs index 332d93c..3923ba0 100644 --- a/src/construct/code_fenced.rs +++ b/src/construct/code_fenced.rs @@ -107,7 +107,7 @@ use crate::construct::{ partial_space_or_tab::{space_or_tab, space_or_tab_min_max}, }; use crate::token::Token; -use crate::tokenizer::{Code, ContentType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, State, Tokenizer}; use crate::util::span::from_exit_event; /// Kind of fences. @@ -188,7 +188,7 @@ struct Info { /// | console.log(1) /// | ~~~ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -199,7 +199,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::CodeFencedFence); tokenizer.go(space_or_tab_min_max(0, max), before_sequence_open)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -211,7 +211,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// | console.log(1) /// | ~~~ /// ``` -fn before_sequence_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before_sequence_open(tokenizer: &mut Tokenizer, code: Code) -> State { let tail = tokenizer.events.last(); let mut prefix = 0; @@ -235,7 +235,7 @@ fn before_sequence_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult }, ) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -247,23 +247,20 @@ fn before_sequence_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult /// | console.log(1) /// | ~~~ /// ``` -fn sequence_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn sequence_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| { - info.size += 1; - sequence_open(t, c, info) - })), - 0, - ) + State::Fn(Box::new(|t, c| { + info.size += 1; + sequence_open(t, c, info) + })) } _ if info.size >= CODE_FENCED_SEQUENCE_SIZE_MIN => { tokenizer.exit(Token::CodeFencedFenceSequence); tokenizer.attempt_opt(space_or_tab(), |t, c| info_before(t, c, info))(tokenizer, code) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -275,7 +272,7 @@ fn sequence_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State /// | console.log(1) /// | ~~~ /// ``` -fn info_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn info_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::CodeFencedFence); @@ -299,12 +296,7 @@ fn info_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResu /// | console.log(1) /// | ~~~ /// ``` -fn info_inside( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, - mut codes: Vec<Code>, -) -> StateFnResult { +fn info_inside(tokenizer: &mut Tokenizer, code: Code, info: Info, mut codes: Vec<Code>) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::Data); @@ -319,14 +311,11 @@ fn info_inside( tokenizer.exit(Token::CodeFencedFenceInfo); tokenizer.attempt_opt(space_or_tab(), |t, c| meta_before(t, c, info))(tokenizer, code) } - Code::Char('`') if info.kind == Kind::GraveAccent => (State::Nok, 0), + Code::Char('`') if info.kind == Kind::GraveAccent => State::Nok, Code::Char(_) => { codes.push(code); tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| info_inside(t, c, info, codes))), - 0, - ) + State::Fn(Box::new(|t, c| info_inside(t, c, info, codes))) } } } @@ -339,7 +328,7 @@ fn info_inside( /// | console.log(1) /// | ~~~ /// ``` -fn meta_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn meta_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::CodeFencedFence); @@ -363,7 +352,7 @@ fn meta_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResu /// | console.log(1) /// | ~~~ /// ``` -fn meta(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn meta(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::Data); @@ -373,10 +362,10 @@ fn meta(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { tokenizer.concrete = true; at_break(tokenizer, code, info) } - Code::Char('`') if info.kind == Kind::GraveAccent => (State::Nok, 0), + Code::Char('`') if info.kind == Kind::GraveAccent => State::Nok, _ => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| meta(t, c, info))), 0) + State::Fn(Box::new(|t, c| meta(t, c, info))) } } } @@ -390,7 +379,7 @@ fn meta(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { /// ^ /// | ~~~ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { tokenizer.check(partial_non_lazy_continuation, |ok| { if ok { Box::new(move |t, c| at_non_lazy_break(t, c, info)) @@ -409,7 +398,7 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult /// ^ /// | ~~~ /// ``` -fn at_non_lazy_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn at_non_lazy_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { let clone = info.clone(); tokenizer.attempt( @@ -432,13 +421,13 @@ fn at_non_lazy_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State /// ^ /// | ~~~ /// ``` -fn close_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn close_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(|t, c| close_start(t, c, info))), 0) + State::Fn(Box::new(|t, c| close_start(t, c, info))) } _ => unreachable!("expected eol"), } @@ -452,7 +441,7 @@ fn close_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResu /// > | ~~~ /// ^ /// ``` -fn close_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn close_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -473,13 +462,13 @@ fn close_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResu /// > | ~~~ /// ^ /// ``` -fn close_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn close_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.enter(Token::CodeFencedFenceSequence); close_sequence(tokenizer, code, info, 0) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -491,20 +480,17 @@ fn close_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRes /// > | ~~~ /// ^ /// ``` -fn close_sequence(tokenizer: &mut Tokenizer, code: Code, info: Info, size: usize) -> StateFnResult { +fn close_sequence(tokenizer: &mut Tokenizer, code: Code, info: Info, size: usize) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| close_sequence(t, c, info, size + 1))), - 0, - ) + State::Fn(Box::new(move |t, c| close_sequence(t, c, info, size + 1))) } _ if size >= CODE_FENCED_SEQUENCE_SIZE_MIN && size >= info.size => { tokenizer.exit(Token::CodeFencedFenceSequence); tokenizer.attempt_opt(space_or_tab(), close_sequence_after)(tokenizer, code) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -516,13 +502,13 @@ fn close_sequence(tokenizer: &mut Tokenizer, code: Code, info: Info, size: usize /// > | ~~~ /// ^ /// ``` -fn close_sequence_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn close_sequence_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::CodeFencedFence); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -534,11 +520,11 @@ fn close_sequence_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult /// ^ /// | ~~~ /// ``` -fn content_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn content_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(|t, c| content_start(t, c, info))), 0) + State::Fn(Box::new(|t, c| content_start(t, c, info))) } /// Before code content, definitely not before a closing fence. /// @@ -548,7 +534,7 @@ fn content_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnR /// ^ /// | ~~~ /// ``` -fn content_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn content_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { tokenizer.go(space_or_tab_min_max(0, info.prefix), |t, c| { content_begin(t, c, info) })(tokenizer, code) @@ -562,7 +548,7 @@ fn content_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRe /// ^ /// | ~~~ /// ``` -fn content_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn content_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_break(tokenizer, code, info) @@ -582,7 +568,7 @@ fn content_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRe /// ^^^^^^^^^^^^^^ /// | ~~~ /// ``` -fn content_continue(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn content_continue(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::CodeFlowChunk); @@ -590,7 +576,7 @@ fn content_continue(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateF } _ => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| content_continue(t, c, info))), 0) + State::Fn(Box::new(|t, c| content_continue(t, c, info))) } } } @@ -603,11 +589,11 @@ fn content_continue(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateF /// > | ~~~ /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.exit(Token::CodeFenced); // Feel free to interrupt. tokenizer.interrupt = false; // No longer concrete. tokenizer.concrete = false; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } diff --git a/src/construct/code_indented.rs b/src/construct/code_indented.rs index 2a8b92f..512a816 100644 --- a/src/construct/code_indented.rs +++ b/src/construct/code_indented.rs @@ -48,7 +48,7 @@ use super::partial_space_or_tab::{space_or_tab, space_or_tab_min_max}; use crate::constant::TAB_SIZE; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of code (indented). /// @@ -60,10 +60,10 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | aaa /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { // Do not interrupt paragraphs. if tokenizer.interrupt || !tokenizer.parse_state.constructs.code_indented { - (State::Nok, 0) + State::Nok } else { tokenizer.enter(Token::CodeIndented); tokenizer.go(space_or_tab_min_max(TAB_SIZE, TAB_SIZE), at_break)(tokenizer, code) @@ -76,7 +76,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | aaa /// ^ ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None => after(tokenizer, code), Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => tokenizer @@ -96,7 +96,7 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | aaa /// ^^^^ /// ``` -fn content(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn content(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::CodeFlowChunk); @@ -104,7 +104,7 @@ fn content(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } _ => { tokenizer.consume(code); - (State::Fn(Box::new(content)), 0) + State::Fn(Box::new(content)) } } } @@ -115,11 +115,11 @@ fn content(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | aaa /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.exit(Token::CodeIndented); // Feel free to interrupt. tokenizer.interrupt = false; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } /// Right at a line ending, trying to parse another indent. @@ -129,16 +129,16 @@ fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | bbb /// ``` -fn further_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn further_start(tokenizer: &mut Tokenizer, code: Code) -> State { if tokenizer.lazy { - (State::Nok, 0) + State::Nok } else { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(further_start)), 0) + State::Fn(Box::new(further_start)) } _ => tokenizer.attempt(space_or_tab_min_max(TAB_SIZE, TAB_SIZE), |ok| { Box::new(if ok { further_end } else { further_begin }) @@ -154,8 +154,8 @@ fn further_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | bbb /// ^ /// ``` -fn further_end(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) +fn further_end(_tokenizer: &mut Tokenizer, code: Code) -> State { + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } /// At the beginning of a line that is not indented enough. @@ -165,7 +165,7 @@ fn further_end(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | bbb /// ^ /// ``` -fn further_begin(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn further_begin(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab(), further_after)(tokenizer, code) } @@ -176,9 +176,9 @@ fn further_begin(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | bbb /// ^ /// ``` -fn further_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn further_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => further_start(tokenizer, code), - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/code_text.rs b/src/construct/code_text.rs index 03ff881..e68d489 100644 --- a/src/construct/code_text.rs +++ b/src/construct/code_text.rs @@ -84,7 +84,7 @@ //! [html-code]: https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-code-element use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of code (text). /// @@ -94,7 +94,7 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// > | \`a` /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let len = tokenizer.events.len(); match code { @@ -108,7 +108,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::CodeTextSequence); sequence_open(tokenizer, code, 0) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -118,13 +118,10 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | `a` /// ^ /// ``` -fn sequence_open(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn sequence_open(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { if let Code::Char('`') = code { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| sequence_open(t, c, size + 1))), - 0, - ) + State::Fn(Box::new(move |t, c| sequence_open(t, c, size + 1))) } else { tokenizer.exit(Token::CodeTextSequence); between(tokenizer, code, size) @@ -137,14 +134,14 @@ fn sequence_open(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnR /// > | `a` /// ^^ /// ``` -fn between(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> StateFnResult { +fn between(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> State { match code { - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(move |t, c| between(t, c, size_open))), 0) + State::Fn(Box::new(move |t, c| between(t, c, size_open))) } Code::Char('`') => { tokenizer.enter(Token::CodeTextSequence); @@ -163,7 +160,7 @@ fn between(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> StateFnRe /// > | `a` /// ^ /// ``` -fn data(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> StateFnResult { +fn data(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r' | '`') => { tokenizer.exit(Token::CodeTextData); @@ -171,7 +168,7 @@ fn data(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> StateFnResul } _ => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| data(t, c, size_open))), 0) + State::Fn(Box::new(move |t, c| data(t, c, size_open))) } } } @@ -182,26 +179,18 @@ fn data(tokenizer: &mut Tokenizer, code: Code, size_open: usize) -> StateFnResul /// > | `a` /// ^ /// ``` -fn sequence_close( - tokenizer: &mut Tokenizer, - code: Code, - size_open: usize, - size: usize, -) -> StateFnResult { +fn sequence_close(tokenizer: &mut Tokenizer, code: Code, size_open: usize, size: usize) -> State { match code { Code::Char('`') => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| { - sequence_close(t, c, size_open, size + 1) - })), - 0, - ) + State::Fn(Box::new(move |t, c| { + sequence_close(t, c, size_open, size + 1) + })) } _ if size_open == size => { tokenizer.exit(Token::CodeTextSequence); tokenizer.exit(Token::CodeText); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } _ => { let index = tokenizer.events.len(); diff --git a/src/construct/definition.rs b/src/construct/definition.rs index 2016cc4..9e43d18 100644 --- a/src/construct/definition.rs +++ b/src/construct/definition.rs @@ -100,7 +100,7 @@ use crate::construct::{ partial_title::{start as title, Options as TitleOptions}, }; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; use crate::util::skip::opt_back as skip_opt_back; /// At the start of a definition. @@ -109,7 +109,7 @@ use crate::util::skip::opt_back as skip_opt_back; /// > | [a]: b "c" /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let definition_before = !tokenizer.events.is_empty() && tokenizer.events[skip_opt_back( &tokenizer.events, @@ -125,7 +125,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { // Note: arbitrary whitespace allowed even if code (indented) is on. tokenizer.attempt_opt(space_or_tab(), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -135,7 +135,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('[') => tokenizer.go( |t, c| { @@ -151,7 +151,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { }, label_after, )(tokenizer, code), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -161,20 +161,17 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn label_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn label_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(':') => { tokenizer.enter(Token::DefinitionMarker); tokenizer.consume(code); tokenizer.exit(Token::DefinitionMarker); - ( - State::Fn(Box::new( - tokenizer.attempt_opt(space_or_tab_eol(), destination_before), - )), - 0, - ) + State::Fn(Box::new( + tokenizer.attempt_opt(space_or_tab_eol(), destination_before), + )) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -184,7 +181,7 @@ fn label_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn destination_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn destination_before(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go( |t, c| { destination( @@ -210,7 +207,7 @@ fn destination_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(title_before, after)(tokenizer, code) } @@ -222,7 +219,7 @@ fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab(), after_whitespace)(tokenizer, code) } @@ -234,15 +231,15 @@ fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn after_whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after_whitespace(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::Definition); // You’d be interrupting. tokenizer.interrupt = true; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -254,7 +251,7 @@ fn after_whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn title_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn title_before(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go(space_or_tab_eol(), title_before_marker)(tokenizer, code) } @@ -265,7 +262,7 @@ fn title_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | "c" /// ^ /// ``` -fn title_before_marker(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn title_before_marker(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go( |t, c| { title( @@ -288,7 +285,7 @@ fn title_before_marker(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn title_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn title_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab(), title_after_after_optional_whitespace)(tokenizer, code) } @@ -298,11 +295,11 @@ fn title_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a]: b "c" /// ^ /// ``` -fn title_after_after_optional_whitespace(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn title_after_after_optional_whitespace(_tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/hard_break_escape.rs b/src/construct/hard_break_escape.rs index 19d430d..617b0ce 100644 --- a/src/construct/hard_break_escape.rs +++ b/src/construct/hard_break_escape.rs @@ -41,7 +41,7 @@ //! [html]: https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-br-element use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of a hard break (escape). /// @@ -50,16 +50,16 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// ^ /// | b /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('\\') if tokenizer.parse_state.constructs.hard_break_escape => { tokenizer.enter(Token::HardBreakEscape); tokenizer.enter(Token::HardBreakEscapeMarker); tokenizer.consume(code); tokenizer.exit(Token::HardBreakEscapeMarker); - (State::Fn(Box::new(inside)), 0) + State::Fn(Box::new(inside)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -70,12 +70,12 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | b /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::HardBreakEscape); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/hard_break_trailing.rs b/src/construct/hard_break_trailing.rs index c5861f7..8ce4201 100644 --- a/src/construct/hard_break_trailing.rs +++ b/src/construct/hard_break_trailing.rs @@ -42,7 +42,7 @@ use crate::constant::HARD_BREAK_PREFIX_SIZE_MIN; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of a hard break (trailing). /// @@ -51,15 +51,15 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// ^ /// | b /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(' ') if tokenizer.parse_state.constructs.hard_break_trailing => { tokenizer.enter(Token::HardBreakTrailing); tokenizer.enter(Token::HardBreakTrailingSpace); tokenizer.consume(code); - (State::Fn(Box::new(|t, c| inside(t, c, 1))), 0) + State::Fn(Box::new(|t, c| inside(t, c, 1))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -70,19 +70,19 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | b /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char(' ') => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| inside(t, c, size + 1))), 0) + State::Fn(Box::new(move |t, c| inside(t, c, size + 1))) } Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') if size >= HARD_BREAK_PREFIX_SIZE_MIN => { tokenizer.exit(Token::HardBreakTrailingSpace); tokenizer.exit(Token::HardBreakTrailing); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/heading_atx.rs b/src/construct/heading_atx.rs index ac36e29..52eca54 100644 --- a/src/construct/heading_atx.rs +++ b/src/construct/heading_atx.rs @@ -57,7 +57,7 @@ use super::partial_space_or_tab::{space_or_tab, space_or_tab_min_max}; use crate::constant::{HEADING_ATX_OPENING_FENCE_SIZE_MAX, TAB_SIZE}; use crate::token::Token; -use crate::tokenizer::{Code, ContentType, Event, EventType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, Event, EventType, State, Tokenizer}; use crate::util::edit_map::EditMap; /// Start of a heading (atx). @@ -66,7 +66,7 @@ use crate::util::edit_map::EditMap; /// > | ## aa /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -77,7 +77,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::HeadingAtx); tokenizer.go(space_or_tab_min_max(0, max), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -87,12 +87,12 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | ## aa /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { if Code::Char('#') == code { tokenizer.enter(Token::HeadingAtxSequence); sequence_open(tokenizer, code, 0) } else { - (State::Nok, 0) + State::Nok } } @@ -102,7 +102,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | ## aa /// ^ /// ``` -fn sequence_open(tokenizer: &mut Tokenizer, code: Code, rank: usize) -> StateFnResult { +fn sequence_open(tokenizer: &mut Tokenizer, code: Code, rank: usize) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') if rank > 0 => { tokenizer.exit(Token::HeadingAtxSequence); @@ -110,18 +110,15 @@ fn sequence_open(tokenizer: &mut Tokenizer, code: Code, rank: usize) -> StateFnR } Code::Char('#') if rank < HEADING_ATX_OPENING_FENCE_SIZE_MAX => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |tokenizer, code| { - sequence_open(tokenizer, code, rank + 1) - })), - 0, - ) + State::Fn(Box::new(move |tokenizer, code| { + sequence_open(tokenizer, code, rank + 1) + })) } _ if rank > 0 => { tokenizer.exit(Token::HeadingAtxSequence); tokenizer.go(space_or_tab(), at_break)(tokenizer, code) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -131,14 +128,14 @@ fn sequence_open(tokenizer: &mut Tokenizer, code: Code, rank: usize) -> StateFnR /// > | ## aa /// ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::HeadingAtx); tokenizer.register_resolver("heading_atx".to_string(), Box::new(resolve)); // Feel free to interrupt. tokenizer.interrupt = false; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.go(space_or_tab(), at_break)(tokenizer, code) @@ -162,10 +159,10 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | ## aa ## /// ^ /// ``` -fn further_sequence(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn further_sequence(tokenizer: &mut Tokenizer, code: Code) -> State { if let Code::Char('#') = code { tokenizer.consume(code); - (State::Fn(Box::new(further_sequence)), 0) + State::Fn(Box::new(further_sequence)) } else { tokenizer.exit(Token::HeadingAtxSequence); at_break(tokenizer, code) @@ -178,7 +175,7 @@ fn further_sequence(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | ## aa /// ^ /// ``` -fn data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn data(tokenizer: &mut Tokenizer, code: Code) -> State { match code { // Note: `#` for closing sequence must be preceded by whitespace, otherwise it’s just text. Code::None | Code::CarriageReturnLineFeed | Code::Char('\t' | '\n' | '\r' | ' ') => { @@ -187,7 +184,7 @@ fn data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } _ => { tokenizer.consume(code); - (State::Fn(Box::new(data)), 0) + State::Fn(Box::new(data)) } } } diff --git a/src/construct/heading_setext.rs b/src/construct/heading_setext.rs index 49d9cd2..828b7f4 100644 --- a/src/construct/heading_setext.rs +++ b/src/construct/heading_setext.rs @@ -60,7 +60,7 @@ use crate::constant::TAB_SIZE; use crate::construct::partial_space_or_tab::{space_or_tab, space_or_tab_min_max}; use crate::token::Token; -use crate::tokenizer::{Code, EventType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, EventType, State, Tokenizer}; use crate::util::{edit_map::EditMap, skip::opt_back as skip_opt_back}; /// Kind of underline. @@ -116,7 +116,7 @@ impl Kind { /// > | == /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -135,7 +135,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { if paragraph_before && !tokenizer.lazy && tokenizer.parse_state.constructs.heading_setext { tokenizer.go(space_or_tab_min_max(0, max), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -146,13 +146,13 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | == /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(char) if char == '-' || char == '=' => { tokenizer.enter(Token::HeadingSetextUnderline); inside(tokenizer, code, Kind::from_char(char)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -163,11 +163,11 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | == /// ^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code, kind: Kind) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code, kind: Kind) -> State { match code { Code::Char(char) if char == kind.as_char() => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| inside(t, c, kind))), 0) + State::Fn(Box::new(move |t, c| inside(t, c, kind))) } _ => { tokenizer.exit(Token::HeadingSetextUnderline); @@ -183,23 +183,23 @@ fn inside(tokenizer: &mut Tokenizer, code: Code, kind: Kind) -> StateFnResult { /// > | == /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { // Feel free to interrupt. tokenizer.interrupt = false; tokenizer.register_resolver("heading_setext".to_string(), Box::new(resolve)); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } - _ => (State::Nok, 0), + _ => State::Nok, } } /// Resolve heading (setext). pub fn resolve(tokenizer: &mut Tokenizer, map: &mut EditMap) -> bool { let mut index = 0; - let mut paragraph_enter: Option<usize> = None; - let mut paragraph_exit: Option<usize> = None; + let mut paragraph_enter = None; + let mut paragraph_exit = None; while index < tokenizer.events.len() { let event = &tokenizer.events[index]; diff --git a/src/construct/html_flow.rs b/src/construct/html_flow.rs index c77a626..7a7c25f 100644 --- a/src/construct/html_flow.rs +++ b/src/construct/html_flow.rs @@ -105,7 +105,7 @@ use crate::construct::{ partial_space_or_tab::{space_or_tab_with_options, Options as SpaceOrTabOptions}, }; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; use crate::util::codes::{parse, serialize}; /// Kind of HTML (flow). @@ -203,7 +203,7 @@ struct Info { /// > | <x /> /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -223,7 +223,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { before, )(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -233,13 +233,13 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | <x /> /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { if Code::Char('<') == code { tokenizer.enter(Token::HtmlFlowData); tokenizer.consume(code); - (State::Fn(Box::new(open)), 0) + State::Fn(Box::new(open)) } else { - (State::Nok, 0) + State::Nok } } @@ -253,7 +253,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | <!--xxx--> /// ^ /// ``` -fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn open(tokenizer: &mut Tokenizer, code: Code) -> State { let mut info = Info { // Assume basic. kind: Kind::Basic, @@ -267,11 +267,11 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { match code { Code::Char('!') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| declaration_open(t, c, info))), 0) + State::Fn(Box::new(|t, c| declaration_open(t, c, info))) } Code::Char('/') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| tag_close_start(t, c, info))), 0) + State::Fn(Box::new(|t, c| tag_close_start(t, c, info))) } Code::Char('?') => { info.kind = Kind::Instruction; @@ -280,16 +280,13 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.concrete = true; // While we’re in an instruction instead of a declaration, we’re on a `?` // right now, so we do need to search for `>`, similar to declarations. - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } Code::Char('A'..='Z' | 'a'..='z') => { info.start_tag = true; tag_name(tokenizer, code, info) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -303,34 +300,28 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | <![CDATA[>&<]]> /// ^ /// ``` -fn declaration_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn declaration_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char('-') => { tokenizer.consume(code); info.kind = Kind::Comment; - ( - State::Fn(Box::new(|t, c| comment_open_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| comment_open_inside(t, c, info))) } Code::Char('[') => { tokenizer.consume(code); info.kind = Kind::Cdata; info.buffer = parse("CDATA["); info.index = 0; - (State::Fn(Box::new(|t, c| cdata_open_inside(t, c, info))), 0) + State::Fn(Box::new(|t, c| cdata_open_inside(t, c, info))) } Code::Char('A'..='Z' | 'a'..='z') => { tokenizer.consume(code); info.kind = Kind::Declaration; // Do not form containers. tokenizer.concrete = true; - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -340,18 +331,15 @@ fn declaration_open(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> St /// > | <!--xxx--> /// ^ /// ``` -fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('-') => { tokenizer.consume(code); // Do not form containers. tokenizer.concrete = true; - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -361,7 +349,7 @@ fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Sta /// > | <![CDATA[>&<]]> /// ^^^^^^ /// ``` -fn cdata_open_inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn cdata_open_inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { if code == info.buffer[info.index] { info.index += 1; tokenizer.consume(code); @@ -370,12 +358,12 @@ fn cdata_open_inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> S info.buffer.clear(); // Do not form containers. tokenizer.concrete = true; - (State::Fn(Box::new(|t, c| continuation(t, c, info))), 0) + State::Fn(Box::new(|t, c| continuation(t, c, info))) } else { - (State::Fn(Box::new(|t, c| cdata_open_inside(t, c, info))), 0) + State::Fn(Box::new(|t, c| cdata_open_inside(t, c, info))) } } else { - (State::Nok, 0) + State::Nok } } @@ -385,14 +373,14 @@ fn cdata_open_inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> S /// > | </x> /// ^ /// ``` -fn tag_close_start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn tag_close_start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char('A'..='Z' | 'a'..='z') => { tokenizer.consume(code); info.buffer.push(code); - (State::Fn(Box::new(|t, c| tag_name(t, c, info))), 0) + State::Fn(Box::new(|t, c| tag_name(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -404,7 +392,7 @@ fn tag_close_start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> Sta /// > | </ab> /// ^^ /// ``` -fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed @@ -425,10 +413,7 @@ fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes // Basic is assumed, no need to set `kind`. if slash { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| basic_self_closing(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| basic_self_closing(t, c, info))) } else { // Do not form containers. tokenizer.concrete = true; @@ -439,7 +424,7 @@ fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes // Do not support complete HTML when interrupting. if tokenizer.interrupt && !tokenizer.lazy { - (State::Nok, 0) + State::Nok } else if info.start_tag { complete_attribute_name_before(tokenizer, code, info) } else { @@ -450,9 +435,9 @@ fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes Code::Char('-' | '0'..='9' | 'A'..='Z' | 'a'..='z') => { tokenizer.consume(code); info.buffer.push(code); - (State::Fn(Box::new(|t, c| tag_name(t, c, info))), 0) + State::Fn(Box::new(|t, c| tag_name(t, c, info))) } - Code::Char(_) => (State::Nok, 0), + Code::Char(_) => State::Nok, } } @@ -462,15 +447,15 @@ fn tag_name(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes /// > | <div/> /// ^ /// ``` -fn basic_self_closing(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn basic_self_closing(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('>') => { tokenizer.consume(code); // Do not form containers. tokenizer.concrete = true; - (State::Fn(Box::new(|t, c| continuation(t, c, info))), 0) + State::Fn(Box::new(|t, c| continuation(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -480,14 +465,11 @@ fn basic_self_closing(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Stat /// > | <x/> /// ^ /// ``` -fn complete_closing_tag_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn complete_closing_tag_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_closing_tag_after(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_closing_tag_after(t, c, info))) } _ => complete_end(tokenizer, code, info), } @@ -512,29 +494,19 @@ fn complete_closing_tag_after(tokenizer: &mut Tokenizer, code: Code, info: Info) /// > | <a > /// ^ /// ``` -fn complete_attribute_name_before( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn complete_attribute_name_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('/') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| complete_end(t, c, info))), 0) + State::Fn(Box::new(|t, c| complete_end(t, c, info))) } Code::Char('0'..='9' | ':' | 'A'..='Z' | '_' | 'a'..='z') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_name(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_name(t, c, info))) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_name_before(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_name_before(t, c, info))) } _ => complete_end(tokenizer, code, info), } @@ -550,14 +522,11 @@ fn complete_attribute_name_before( /// > | <a b> /// ^ /// ``` -fn complete_attribute_name(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn complete_attribute_name(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('-' | '.' | '0'..='9' | ':' | 'A'..='Z' | '_' | 'a'..='z') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_name(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_name(t, c, info))) } _ => complete_attribute_name_after(tokenizer, code, info), } @@ -572,25 +541,15 @@ fn complete_attribute_name(tokenizer: &mut Tokenizer, code: Code, info: Info) -> /// > | <a b=c> /// ^ /// ``` -fn complete_attribute_name_after( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn complete_attribute_name_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('=') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_value_before(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_value_before(t, c, info))) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_name_after(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_name_after(t, c, info))) } _ => complete_attribute_name_before(tokenizer, code, info), } @@ -605,27 +564,17 @@ fn complete_attribute_name_after( /// > | <a b="c"> /// ^ /// ``` -fn complete_attribute_value_before( - tokenizer: &mut Tokenizer, - code: Code, - mut info: Info, -) -> StateFnResult { +fn complete_attribute_value_before(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { - Code::None | Code::Char('<' | '=' | '>' | '`') => (State::Nok, 0), + Code::None | Code::Char('<' | '=' | '>' | '`') => State::Nok, Code::Char('"' | '\'') => { tokenizer.consume(code); info.quote = Some(QuoteKind::from_code(code)); - ( - State::Fn(Box::new(|t, c| complete_attribute_value_quoted(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_value_quoted(t, c, info))) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_value_before(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_value_before(t, c, info))) } _ => complete_attribute_value_unquoted(tokenizer, code, info), } @@ -639,28 +588,18 @@ fn complete_attribute_value_before( /// > | <a b='c'> /// ^ /// ``` -fn complete_attribute_value_quoted( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn complete_attribute_value_quoted(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { - Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => (State::Nok, 0), + Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => State::Nok, Code::Char(char) if char == info.quote.as_ref().unwrap().as_char() => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| { - complete_attribute_value_quoted_after(t, c, info) - })), - 0, - ) + State::Fn(Box::new(|t, c| { + complete_attribute_value_quoted_after(t, c, info) + })) } _ => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| complete_attribute_value_quoted(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| complete_attribute_value_quoted(t, c, info))) } } } @@ -671,11 +610,7 @@ fn complete_attribute_value_quoted( /// > | <a b=c> /// ^ /// ``` -fn complete_attribute_value_unquoted( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn complete_attribute_value_unquoted(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed @@ -685,12 +620,9 @@ fn complete_attribute_value_unquoted( } Code::Char(_) => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| { - complete_attribute_value_unquoted(t, c, info) - })), - 0, - ) + State::Fn(Box::new(|t, c| { + complete_attribute_value_unquoted(t, c, info) + })) } } } @@ -706,12 +638,12 @@ fn complete_attribute_value_quoted_after( tokenizer: &mut Tokenizer, code: Code, info: Info, -) -> StateFnResult { +) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ' | '/' | '>') => { complete_attribute_name_before(tokenizer, code, info) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -721,13 +653,13 @@ fn complete_attribute_value_quoted_after( /// > | <a b="c"> /// ^ /// ``` -fn complete_end(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn complete_end(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('>') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| complete_after(t, c, info))), 0) + State::Fn(Box::new(|t, c| complete_after(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -737,7 +669,7 @@ fn complete_end(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRes /// > | <x> /// ^ /// ``` -fn complete_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn complete_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { // Do not form containers. @@ -746,9 +678,9 @@ fn complete_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnR } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| complete_after(t, c, info))), 0) + State::Fn(Box::new(|t, c| complete_after(t, c, info))) } - Code::Char(_) => (State::Nok, 0), + Code::Char(_) => State::Nok, } } @@ -758,44 +690,29 @@ fn complete_after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnR /// > | <!--xxx--> /// ^ /// ``` -fn continuation(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('-') if info.kind == Kind::Comment => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_comment_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_comment_inside(t, c, info))) } Code::Char('<') if info.kind == Kind::Raw => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_raw_tag_open(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_raw_tag_open(t, c, info))) } Code::Char('>') if info.kind == Kind::Declaration => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_close(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_close(t, c, info))) } Code::Char('?') if info.kind == Kind::Instruction => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } Code::Char(']') if info.kind == Kind::Cdata => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| { - continuation_character_data_inside(t, c, info) - })), - 0, - ) + State::Fn(Box::new(|t, c| { + continuation_character_data_inside(t, c, info) + })) } Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') if info.kind == Kind::Basic || info.kind == Kind::Complete => @@ -815,7 +732,7 @@ fn continuation(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRes } _ => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| continuation(t, c, info))), 0) + State::Fn(Box::new(|t, c| continuation(t, c, info))) } } } @@ -827,7 +744,7 @@ fn continuation(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnRes /// ^ /// | asd /// ``` -fn continuation_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { tokenizer.check(partial_non_lazy_continuation, |ok| { if ok { Box::new(move |t, c| continuation_start_non_lazy(t, c, info)) @@ -844,16 +761,13 @@ fn continuation_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Stat /// ^ /// | asd /// ``` -fn continuation_start_non_lazy(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_start_non_lazy(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - ( - State::Fn(Box::new(|t, c| continuation_before(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_before(t, c, info))) } _ => unreachable!("expected eol"), } @@ -866,7 +780,7 @@ fn continuation_start_non_lazy(tokenizer: &mut Tokenizer, code: Code, info: Info /// > | asd /// ^ /// ``` -fn continuation_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { continuation_start(tokenizer, code, info) @@ -884,14 +798,11 @@ fn continuation_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Sta /// > | <!--xxx--> /// ^ /// ``` -fn continuation_comment_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_comment_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('-') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } _ => continuation(tokenizer, code, info), } @@ -903,14 +814,11 @@ fn continuation_comment_inside(tokenizer: &mut Tokenizer, code: Code, info: Info /// > | <script>console.log(1)</script> /// ^ /// ``` -fn continuation_raw_tag_open(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_raw_tag_open(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('/') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_raw_end_tag(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_raw_end_tag(t, c, info))) } _ => continuation(tokenizer, code, info), } @@ -922,11 +830,7 @@ fn continuation_raw_tag_open(tokenizer: &mut Tokenizer, code: Code, info: Info) /// > | <script>console.log(1)</script> /// ^^^^^^ /// ``` -fn continuation_raw_end_tag( - tokenizer: &mut Tokenizer, - code: Code, - mut info: Info, -) -> StateFnResult { +fn continuation_raw_end_tag(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char('>') => { let tag_name_buffer = serialize(&info.buffer, false).to_lowercase(); @@ -934,10 +838,7 @@ fn continuation_raw_end_tag( if HTML_RAW_NAMES.contains(&tag_name_buffer.as_str()) { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_close(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_close(t, c, info))) } else { continuation(tokenizer, code, info) } @@ -945,10 +846,7 @@ fn continuation_raw_end_tag( Code::Char('A'..='Z' | 'a'..='z') if info.buffer.len() < HTML_RAW_SIZE_MAX => { tokenizer.consume(code); info.buffer.push(code); - ( - State::Fn(Box::new(|t, c| continuation_raw_end_tag(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_raw_end_tag(t, c, info))) } _ => { info.buffer.clear(); @@ -963,18 +861,11 @@ fn continuation_raw_end_tag( /// > | <![CDATA[>&<]]> /// ^ /// ``` -fn continuation_character_data_inside( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn continuation_character_data_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char(']') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } _ => continuation(tokenizer, code, info), } @@ -994,25 +885,15 @@ fn continuation_character_data_inside( /// > | <![CDATA[>&<]]> /// ^ /// ``` -fn continuation_declaration_inside( - tokenizer: &mut Tokenizer, - code: Code, - info: Info, -) -> StateFnResult { +fn continuation_declaration_inside(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('>') => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_close(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_close(t, c, info))) } Code::Char('-') if info.kind == Kind::Comment => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_declaration_inside(t, c, info))) } _ => continuation(tokenizer, code, info), } @@ -1024,7 +905,7 @@ fn continuation_declaration_inside( /// > | <!doctype> /// ^ /// ``` -fn continuation_close(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn continuation_close(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::HtmlFlowData); @@ -1032,10 +913,7 @@ fn continuation_close(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Stat } _ => { tokenizer.consume(code); - ( - State::Fn(Box::new(|t, c| continuation_close(t, c, info))), - 0, - ) + State::Fn(Box::new(|t, c| continuation_close(t, c, info))) } } } @@ -1046,13 +924,13 @@ fn continuation_close(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Stat /// > | <!doctype> /// ^ /// ``` -fn continuation_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn continuation_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.exit(Token::HtmlFlow); // Feel free to interrupt. tokenizer.interrupt = false; // No longer concrete. tokenizer.concrete = false; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } /// Before a line ending, expecting a blank line. @@ -1062,9 +940,9 @@ fn continuation_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | /// ``` -fn blank_line_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn blank_line_before(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(blank_line)), 0) + State::Fn(Box::new(blank_line)) } diff --git a/src/construct/html_text.rs b/src/construct/html_text.rs index 1696f68..f1ed5c7 100644 --- a/src/construct/html_text.rs +++ b/src/construct/html_text.rs @@ -56,7 +56,7 @@ use crate::construct::partial_space_or_tab::space_or_tab; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFn, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, StateFn, Tokenizer}; use crate::util::codes::parse; /// Start of HTML (text) @@ -65,14 +65,14 @@ use crate::util::codes::parse; /// > | a <b> c /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { if Code::Char('<') == code && tokenizer.parse_state.constructs.html_text { tokenizer.enter(Token::HtmlText); tokenizer.enter(Token::HtmlTextData); tokenizer.consume(code); - (State::Fn(Box::new(open)), 0) + State::Fn(Box::new(open)) } else { - (State::Nok, 0) + State::Nok } } @@ -86,25 +86,25 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <!--b--> c /// ^ /// ``` -fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('!') => { tokenizer.consume(code); - (State::Fn(Box::new(declaration_open)), 0) + State::Fn(Box::new(declaration_open)) } Code::Char('/') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_close_start)), 0) + State::Fn(Box::new(tag_close_start)) } Code::Char('?') => { tokenizer.consume(code); - (State::Fn(Box::new(instruction)), 0) + State::Fn(Box::new(instruction)) } Code::Char('A'..='Z' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open)), 0) + State::Fn(Box::new(tag_open)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -118,25 +118,22 @@ fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <![CDATA[>&<]]> c /// ^ /// ``` -fn declaration_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn declaration_open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-') => { tokenizer.consume(code); - (State::Fn(Box::new(comment_open_inside)), 0) + State::Fn(Box::new(comment_open_inside)) } Code::Char('[') => { tokenizer.consume(code); let buffer = parse("CDATA["); - ( - State::Fn(Box::new(|t, c| cdata_open_inside(t, c, buffer, 0))), - 0, - ) + State::Fn(Box::new(|t, c| cdata_open_inside(t, c, buffer, 0))) } Code::Char('A'..='Z' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(declaration)), 0) + State::Fn(Box::new(declaration)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -146,13 +143,13 @@ fn declaration_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <!--b--> c /// ^ /// ``` -fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-') => { tokenizer.consume(code); - (State::Fn(Box::new(comment_start)), 0) + State::Fn(Box::new(comment_start)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -169,12 +166,12 @@ fn comment_open_inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ``` /// /// [html_flow]: crate::construct::html_flow -fn comment_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn comment_start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None | Code::Char('>') => (State::Nok, 0), + Code::None | Code::Char('>') => State::Nok, Code::Char('-') => { tokenizer.consume(code); - (State::Fn(Box::new(comment_start_dash)), 0) + State::Fn(Box::new(comment_start_dash)) } _ => comment(tokenizer, code), } @@ -193,9 +190,9 @@ fn comment_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ``` /// /// [html_flow]: crate::construct::html_flow -fn comment_start_dash(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn comment_start_dash(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None | Code::Char('>') => (State::Nok, 0), + Code::None | Code::Char('>') => State::Nok, _ => comment(tokenizer, code), } } @@ -206,19 +203,19 @@ fn comment_start_dash(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <!--b--> c /// ^ /// ``` -fn comment(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn comment(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(comment)) } Code::Char('-') => { tokenizer.consume(code); - (State::Fn(Box::new(comment_close)), 0) + State::Fn(Box::new(comment_close)) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(comment)), 0) + State::Fn(Box::new(comment)) } } } @@ -229,11 +226,11 @@ fn comment(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <!--b--> c /// ^ /// ``` -fn comment_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn comment_close(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-') => { tokenizer.consume(code); - (State::Fn(Box::new(end)), 0) + State::Fn(Box::new(end)) } _ => comment(tokenizer, code), } @@ -250,22 +247,19 @@ fn cdata_open_inside( code: Code, buffer: Vec<Code>, index: usize, -) -> StateFnResult { +) -> State { if code == buffer[index] { tokenizer.consume(code); if index + 1 == buffer.len() { - (State::Fn(Box::new(cdata)), 0) + State::Fn(Box::new(cdata)) } else { - ( - State::Fn(Box::new(move |t, c| { - cdata_open_inside(t, c, buffer, index + 1) - })), - 0, - ) + State::Fn(Box::new(move |t, c| { + cdata_open_inside(t, c, buffer, index + 1) + })) } } else { - (State::Nok, 0) + State::Nok } } @@ -275,19 +269,19 @@ fn cdata_open_inside( /// > | a <![CDATA[>&<]]> b /// ^^^ /// ``` -fn cdata(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn cdata(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(cdata)) } Code::Char(']') => { tokenizer.consume(code); - (State::Fn(Box::new(cdata_close)), 0) + State::Fn(Box::new(cdata_close)) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(cdata)), 0) + State::Fn(Box::new(cdata)) } } } @@ -298,11 +292,11 @@ fn cdata(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <![CDATA[>&<]]> b /// ^ /// ``` -fn cdata_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn cdata_close(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(']') => { tokenizer.consume(code); - (State::Fn(Box::new(cdata_end)), 0) + State::Fn(Box::new(cdata_end)) } _ => cdata(tokenizer, code), } @@ -314,7 +308,7 @@ fn cdata_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <![CDATA[>&<]]> b /// ^ /// ``` -fn cdata_end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn cdata_end(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => end(tokenizer, code), Code::Char(']') => cdata_close(tokenizer, code), @@ -328,7 +322,7 @@ fn cdata_end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <!b> c /// ^ /// ``` -fn declaration(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn declaration(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::Char('>') => end(tokenizer, code), Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { @@ -336,7 +330,7 @@ fn declaration(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } _ => { tokenizer.consume(code); - (State::Fn(Box::new(declaration)), 0) + State::Fn(Box::new(declaration)) } } } @@ -347,19 +341,19 @@ fn declaration(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <?b?> c /// ^ /// ``` -fn instruction(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn instruction(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(instruction)) } Code::Char('?') => { tokenizer.consume(code); - (State::Fn(Box::new(instruction_close)), 0) + State::Fn(Box::new(instruction_close)) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(instruction)), 0) + State::Fn(Box::new(instruction)) } } } @@ -370,7 +364,7 @@ fn instruction(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <?b?> c /// ^ /// ``` -fn instruction_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn instruction_close(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => end(tokenizer, code), _ => instruction(tokenizer, code), @@ -383,13 +377,13 @@ fn instruction_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a </b> c /// ^ /// ``` -fn tag_close_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_close_start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('A'..='Z' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_close)), 0) + State::Fn(Box::new(tag_close)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -399,11 +393,11 @@ fn tag_close_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a </b> c /// ^ /// ``` -fn tag_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_close(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-' | '0'..='9' | 'A'..='Z' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_close)), 0) + State::Fn(Box::new(tag_close)) } _ => tag_close_between(tokenizer, code), } @@ -415,14 +409,14 @@ fn tag_close(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a </b> c /// ^ /// ``` -fn tag_close_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_close_between(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(tag_close_between)) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_close_between)), 0) + State::Fn(Box::new(tag_close_between)) } _ => end(tokenizer, code), } @@ -434,16 +428,16 @@ fn tag_close_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <b> c /// ^ /// ``` -fn tag_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-' | '0'..='9' | 'A'..='Z' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open)), 0) + State::Fn(Box::new(tag_open)) } Code::CarriageReturnLineFeed | Code::VirtualSpace | Code::Char('\t' | '\n' | '\r' | ' ' | '/' | '>') => tag_open_between(tokenizer, code), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -453,22 +447,22 @@ fn tag_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <b> c /// ^ /// ``` -fn tag_open_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_between(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(tag_open_between)) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_between)), 0) + State::Fn(Box::new(tag_open_between)) } Code::Char('/') => { tokenizer.consume(code); - (State::Fn(Box::new(end)), 0) + State::Fn(Box::new(end)) } Code::Char(':' | 'A'..='Z' | '_' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_name)), 0) + State::Fn(Box::new(tag_open_attribute_name)) } _ => end(tokenizer, code), } @@ -480,11 +474,11 @@ fn tag_open_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a <b c> d /// ^ /// ``` -fn tag_open_attribute_name(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_attribute_name(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('-' | '.' | '0'..='9' | ':' | 'A'..='Z' | '_' | 'a'..='z') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_name)), 0) + State::Fn(Box::new(tag_open_attribute_name)) } _ => tag_open_attribute_name_after(tokenizer, code), } @@ -497,18 +491,18 @@ fn tag_open_attribute_name(tokenizer: &mut Tokenizer, code: Code) -> StateFnResu /// > | a <b c> d /// ^ /// ``` -fn tag_open_attribute_name_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_attribute_name_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(tag_open_attribute_name_after)) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_name_after)), 0) + State::Fn(Box::new(tag_open_attribute_name_after)) } Code::Char('=') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_value_before)), 0) + State::Fn(Box::new(tag_open_attribute_value_before)) } _ => tag_open_between(tokenizer, code), } @@ -521,28 +515,25 @@ fn tag_open_attribute_name_after(tokenizer: &mut Tokenizer, code: Code) -> State /// > | a <b c=d> e /// ^ /// ``` -fn tag_open_attribute_value_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_attribute_value_before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None | Code::Char('<' | '=' | '>' | '`') => (State::Nok, 0), + Code::None | Code::Char('<' | '=' | '>' | '`') => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { at_line_ending(tokenizer, code, Box::new(tag_open_attribute_value_before)) } Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_value_before)), 0) + State::Fn(Box::new(tag_open_attribute_value_before)) } Code::Char(char) if char == '"' || char == '\'' => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| { - tag_open_attribute_value_quoted(t, c, char) - })), - 0, - ) + State::Fn(Box::new(move |t, c| { + tag_open_attribute_value_quoted(t, c, char) + })) } Code::Char(_) => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_value_unquoted)), 0) + State::Fn(Box::new(tag_open_attribute_value_unquoted)) } } } @@ -553,13 +544,9 @@ fn tag_open_attribute_value_before(tokenizer: &mut Tokenizer, code: Code) -> Sta /// > | a <b c="d"> e /// ^ /// ``` -fn tag_open_attribute_value_quoted( - tokenizer: &mut Tokenizer, - code: Code, - marker: char, -) -> StateFnResult { +fn tag_open_attribute_value_quoted(tokenizer: &mut Tokenizer, code: Code, marker: char) -> State { match code { - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => at_line_ending( tokenizer, code, @@ -567,19 +554,13 @@ fn tag_open_attribute_value_quoted( ), Code::Char(char) if char == marker => { tokenizer.consume(code); - ( - State::Fn(Box::new(tag_open_attribute_value_quoted_after)), - 0, - ) + State::Fn(Box::new(tag_open_attribute_value_quoted_after)) } _ => { tokenizer.consume(code); - ( - State::Fn(Box::new(move |t, c| { - tag_open_attribute_value_quoted(t, c, marker) - })), - 0, - ) + State::Fn(Box::new(move |t, c| { + tag_open_attribute_value_quoted(t, c, marker) + })) } } } @@ -590,15 +571,15 @@ fn tag_open_attribute_value_quoted( /// > | a <b c=d> e /// ^ /// ``` -fn tag_open_attribute_value_unquoted(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_attribute_value_unquoted(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None | Code::Char('"' | '\'' | '<' | '=' | '`') => (State::Nok, 0), + Code::None | Code::Char('"' | '\'' | '<' | '=' | '`') => State::Nok, Code::CarriageReturnLineFeed | Code::VirtualSpace | Code::Char('\t' | '\n' | '\r' | ' ' | '/' | '>') => tag_open_between(tokenizer, code), Code::Char(_) => { tokenizer.consume(code); - (State::Fn(Box::new(tag_open_attribute_value_unquoted)), 0) + State::Fn(Box::new(tag_open_attribute_value_unquoted)) } } } @@ -610,12 +591,12 @@ fn tag_open_attribute_value_unquoted(tokenizer: &mut Tokenizer, code: Code) -> S /// > | a <b c="d"> e /// ^ /// ``` -fn tag_open_attribute_value_quoted_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn tag_open_attribute_value_quoted_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::VirtualSpace | Code::Char('\t' | '\n' | '\r' | ' ' | '>' | '/') => tag_open_between(tokenizer, code), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -625,15 +606,15 @@ fn tag_open_attribute_value_quoted_after(tokenizer: &mut Tokenizer, code: Code) /// > | a <b c="d"> e /// ^ /// ``` -fn end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn end(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('>') => { tokenizer.consume(code); tokenizer.exit(Token::HtmlTextData); tokenizer.exit(Token::HtmlText); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -647,21 +628,14 @@ fn end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | b--> /// ``` -fn at_line_ending( - tokenizer: &mut Tokenizer, - code: Code, - return_state: Box<StateFn>, -) -> StateFnResult { +fn at_line_ending(tokenizer: &mut Tokenizer, code: Code, return_state: Box<StateFn>) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::HtmlTextData); tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - ( - State::Fn(Box::new(|t, c| after_line_ending(t, c, return_state))), - 0, - ) + State::Fn(Box::new(|t, c| after_line_ending(t, c, return_state))) } _ => unreachable!("expected eol"), } @@ -677,11 +651,7 @@ fn at_line_ending( /// > | b--> /// ^ /// ``` -fn after_line_ending( - tokenizer: &mut Tokenizer, - code: Code, - return_state: Box<StateFn>, -) -> StateFnResult { +fn after_line_ending(tokenizer: &mut Tokenizer, code: Code, return_state: Box<StateFn>) -> State { tokenizer.attempt_opt(space_or_tab(), |t, c| { after_line_ending_prefix(t, c, return_state) })(tokenizer, code) @@ -701,7 +671,7 @@ fn after_line_ending_prefix( tokenizer: &mut Tokenizer, code: Code, return_state: Box<StateFn>, -) -> StateFnResult { +) -> State { tokenizer.enter(Token::HtmlTextData); return_state(tokenizer, code) } diff --git a/src/construct/label_end.rs b/src/construct/label_end.rs index 504571d..0b9654d 100644 --- a/src/construct/label_end.rs +++ b/src/construct/label_end.rs @@ -154,7 +154,7 @@ use crate::construct::{ partial_title::{start as title, Options as TitleOptions}, }; use crate::token::Token; -use crate::tokenizer::{Code, Event, EventType, Media, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, Event, EventType, Media, State, Tokenizer}; use crate::util::{ edit_map::EditMap, normalize_identifier::normalize_identifier, @@ -181,9 +181,9 @@ struct Info { /// ^ /// > | [a] b /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { if Code::Char(']') == code && tokenizer.parse_state.constructs.label_end { - let mut label_start_index: Option<usize> = None; + let mut label_start_index = None; let mut index = tokenizer.label_start_stack.len(); while index > 0 { @@ -230,11 +230,11 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.exit(Token::LabelMarker); tokenizer.exit(Token::LabelEnd); - return (State::Fn(Box::new(move |t, c| after(t, c, info))), 0); + return State::Fn(Box::new(move |t, c| after(t, c, info))); } } - (State::Nok, 0) + State::Nok } /// After `]`. @@ -249,7 +249,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a] b /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { let defined = tokenizer.parse_state.definitions.contains(&info.media.id); match code { @@ -297,7 +297,7 @@ fn after(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { /// > | [a] b /// ^ /// ``` -fn reference_not_full(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn reference_not_full(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { tokenizer.attempt(collapsed_reference, move |is_ok| { Box::new(move |t, c| { if is_ok { @@ -321,7 +321,7 @@ fn reference_not_full(tokenizer: &mut Tokenizer, code: Code, info: Info) -> Stat /// > | [a] b /// ^ /// ``` -fn ok(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn ok(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { // Remove this one and everything after it. let mut left = tokenizer .label_start_stack @@ -346,7 +346,7 @@ fn ok(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { info.media.end.1 = tokenizer.events.len() - 1; tokenizer.media_list.push(info.media); tokenizer.register_resolver_before("media".to_string(), Box::new(resolve_media)); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } /// Done, it’s nothing. @@ -361,13 +361,13 @@ fn ok(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { /// > | [a] b /// ^ /// ``` -fn nok(tokenizer: &mut Tokenizer, _code: Code, label_start_index: usize) -> StateFnResult { +fn nok(tokenizer: &mut Tokenizer, _code: Code, label_start_index: usize) -> State { let label_start = tokenizer .label_start_stack .get_mut(label_start_index) .unwrap(); label_start.balanced = true; - (State::Nok, 0) + State::Nok } /// Before a resource, at `(`. @@ -376,14 +376,14 @@ fn nok(tokenizer: &mut Tokenizer, _code: Code, label_start_index: usize) -> Stat /// > | [a](b) c /// ^ /// ``` -fn resource(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn resource(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('(') => { tokenizer.enter(Token::Resource); tokenizer.enter(Token::ResourceMarker); tokenizer.consume(code); tokenizer.exit(Token::ResourceMarker); - (State::Fn(Box::new(resource_start)), 0) + State::Fn(Box::new(resource_start)) } _ => unreachable!("expected `(`"), } @@ -395,7 +395,7 @@ fn resource(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b) c /// ^ /// ``` -fn resource_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn resource_start(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab_eol(), resource_open)(tokenizer, code) } @@ -405,7 +405,7 @@ fn resource_start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b) c /// ^ /// ``` -fn resource_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn resource_open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(')') => resource_end(tokenizer, code), _ => tokenizer.go( @@ -434,7 +434,7 @@ fn resource_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b) c /// ^ /// ``` -fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt(space_or_tab_eol(), |ok| { Box::new(if ok { resource_between } else { resource_end }) })(tokenizer, code) @@ -446,7 +446,7 @@ fn destination_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b ) c /// ^ /// ``` -fn resource_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn resource_between(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('"' | '\'' | '(') => tokenizer.go( |t, c| { @@ -472,7 +472,7 @@ fn resource_between(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b "c") d /// ^ /// ``` -fn title_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn title_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.attempt_opt(space_or_tab_eol(), resource_end)(tokenizer, code) } @@ -482,16 +482,16 @@ fn title_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a](b) d /// ^ /// ``` -fn resource_end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn resource_end(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(')') => { tokenizer.enter(Token::ResourceMarker); tokenizer.consume(code); tokenizer.exit(Token::ResourceMarker); tokenizer.exit(Token::Resource); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -501,7 +501,7 @@ fn resource_end(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a][b] d /// ^ /// ``` -fn full_reference(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn full_reference(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('[') => tokenizer.go( |t, c| { @@ -527,7 +527,7 @@ fn full_reference(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a][b] d /// ^ /// ``` -fn full_reference_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn full_reference_after(tokenizer: &mut Tokenizer, code: Code) -> State { let events = &tokenizer.events; let mut index = events.len() - 1; let mut start: Option<usize> = None; @@ -559,9 +559,9 @@ fn full_reference_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult false, ))) { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } else { - (State::Nok, 0) + State::Nok } } @@ -573,16 +573,16 @@ fn full_reference_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult /// > | [a][] d /// ^ /// ``` -fn collapsed_reference(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn collapsed_reference(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('[') => { tokenizer.enter(Token::Reference); tokenizer.enter(Token::ReferenceMarker); tokenizer.consume(code); tokenizer.exit(Token::ReferenceMarker); - (State::Fn(Box::new(collapsed_reference_open)), 0) + State::Fn(Box::new(collapsed_reference_open)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -594,16 +594,16 @@ fn collapsed_reference(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | [a][] d /// ^ /// ``` -fn collapsed_reference_open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn collapsed_reference_open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char(']') => { tokenizer.enter(Token::ReferenceMarker); tokenizer.consume(code); tokenizer.exit(Token::ReferenceMarker); tokenizer.exit(Token::Reference); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/label_start_image.rs b/src/construct/label_start_image.rs index 3764f20..6738ebe 100644 --- a/src/construct/label_start_image.rs +++ b/src/construct/label_start_image.rs @@ -30,7 +30,7 @@ use super::label_end::resolve_media; use crate::token::Token; -use crate::tokenizer::{Code, LabelStart, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, LabelStart, State, Tokenizer}; /// Start of label (image) start. /// @@ -38,16 +38,16 @@ use crate::tokenizer::{Code, LabelStart, State, StateFnResult, Tokenizer}; /// > | a ![b] c /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('!') if tokenizer.parse_state.constructs.label_start_image => { tokenizer.enter(Token::LabelImage); tokenizer.enter(Token::LabelImageMarker); tokenizer.consume(code); tokenizer.exit(Token::LabelImageMarker); - (State::Fn(Box::new(open)), 0) + State::Fn(Box::new(open)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -57,7 +57,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | a ![b] c /// ^ /// ``` -pub fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn open(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('[') => { tokenizer.enter(Token::LabelMarker); @@ -71,8 +71,8 @@ pub fn open(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { inactive: false, }); tokenizer.register_resolver_before("media".to_string(), Box::new(resolve_media)); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/label_start_link.rs b/src/construct/label_start_link.rs index 404b91a..9462ba7 100644 --- a/src/construct/label_start_link.rs +++ b/src/construct/label_start_link.rs @@ -29,7 +29,7 @@ use super::label_end::resolve_media; use crate::token::Token; -use crate::tokenizer::{Code, LabelStart, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, LabelStart, State, Tokenizer}; /// Start of label (link) start. /// @@ -37,7 +37,7 @@ use crate::tokenizer::{Code, LabelStart, State, StateFnResult, Tokenizer}; /// > | a [b] c /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('[') if tokenizer.parse_state.constructs.label_start_link => { let start = tokenizer.events.len(); @@ -52,8 +52,8 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { inactive: false, }); tokenizer.register_resolver_before("media".to_string(), Box::new(resolve_media)); - (State::Ok, 0) + State::Ok(0) } - _ => (State::Nok, 0), + _ => State::Nok, } } diff --git a/src/construct/list.rs b/src/construct/list.rs index 289398a..96113e6 100644 --- a/src/construct/list.rs +++ b/src/construct/list.rs @@ -50,7 +50,7 @@ use crate::construct::{ thematic_break::start as thematic_break, }; use crate::token::Token; -use crate::tokenizer::{Code, EventType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, EventType, State, Tokenizer}; use crate::util::{ edit_map::EditMap, skip, @@ -137,7 +137,7 @@ impl Kind { /// > | * a /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -148,7 +148,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::ListItem); tokenizer.go(space_or_tab_min_max(0, max), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -158,7 +158,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { // Unordered. Code::Char('*' | '+' | '-') => tokenizer.check(thematic_break, |ok| { @@ -170,7 +170,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::ListItemValue); inside(tokenizer, code, 0) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -182,7 +182,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn before_unordered(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before_unordered(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.enter(Token::ListItemPrefix); marker(tokenizer, code) } @@ -193,17 +193,17 @@ fn before_unordered(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | 1. a /// ^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code, size: usize) -> State { match code { Code::Char(char) if char.is_ascii_digit() && size + 1 < LIST_ITEM_VALUE_SIZE_MAX => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| inside(t, c, size + 1))), 0) + State::Fn(Box::new(move |t, c| inside(t, c, size + 1))) } Code::Char('.' | ')') if !tokenizer.interrupt || size < 2 => { tokenizer.exit(Token::ListItemValue); marker(tokenizer, code) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -215,11 +215,11 @@ fn inside(tokenizer: &mut Tokenizer, code: Code, size: usize) -> StateFnResult { /// > | 1. b /// ^ /// ``` -fn marker(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn marker(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.enter(Token::ListItemMarker); tokenizer.consume(code); tokenizer.exit(Token::ListItemMarker); - (State::Fn(Box::new(marker_after)), 0) + State::Fn(Box::new(marker_after)) } /// After a list item marker. @@ -230,7 +230,7 @@ fn marker(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | 1. b /// ^ /// ``` -fn marker_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn marker_after(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.check(blank_line, move |ok| { if ok { Box::new(|t, c| after(t, c, true)) @@ -246,7 +246,7 @@ fn marker_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn marker_after_not_blank(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn marker_after_not_blank(tokenizer: &mut Tokenizer, code: Code) -> State { // Attempt to parse up to the largest allowed indent, `nok` if there is more whitespace. tokenizer.attempt(whitespace, move |ok| { if ok { @@ -263,7 +263,7 @@ fn marker_after_not_blank(tokenizer: &mut Tokenizer, code: Code) -> StateFnResul /// > | * a /// ^ /// ``` -fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go(space_or_tab_min_max(1, TAB_SIZE), whitespace_after)(tokenizer, code) } @@ -273,11 +273,11 @@ fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn whitespace_after(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn whitespace_after(_tokenizer: &mut Tokenizer, code: Code) -> State { if matches!(code, Code::VirtualSpace | Code::Char('\t' | ' ')) { - (State::Nok, 0) + State::Nok } else { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } @@ -287,15 +287,15 @@ fn whitespace_after(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn prefix_other(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn prefix_other(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.enter(Token::SpaceOrTab); tokenizer.consume(code); tokenizer.exit(Token::SpaceOrTab); - (State::Fn(Box::new(|t, c| after(t, c, false))), 0) + State::Fn(Box::new(|t, c| after(t, c, false))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -305,9 +305,9 @@ fn prefix_other(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | * a /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code, blank: bool) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code, blank: bool) -> State { if blank && tokenizer.interrupt { - (State::Nok, 0) + State::Nok } else { let start = skip::to_back( &tokenizer.events, @@ -323,7 +323,7 @@ fn after(tokenizer: &mut Tokenizer, code: Code, blank: bool) -> StateFnResult { tokenizer.exit(Token::ListItemPrefix); tokenizer.register_resolver_before("list_item".to_string(), Box::new(resolve_list_item)); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } @@ -334,7 +334,7 @@ fn after(tokenizer: &mut Tokenizer, code: Code, blank: bool) -> StateFnResult { /// > | b /// ^ /// ``` -pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.check(blank_line, |ok| { Box::new(if ok { blank_cont } else { not_blank_cont }) })(tokenizer, code) @@ -348,12 +348,12 @@ pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ^ /// | b /// ``` -pub fn blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn blank_cont(tokenizer: &mut Tokenizer, code: Code) -> State { let container = tokenizer.container.as_ref().unwrap(); let size = container.size; if container.blank_initial { - (State::Nok, 0) + State::Nok } else { // Consume, optionally, at most `size`. tokenizer.go(space_or_tab_min_max(0, size), ok)(tokenizer, code) @@ -367,7 +367,7 @@ pub fn blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | b /// ^ /// ``` -pub fn not_blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn not_blank_cont(tokenizer: &mut Tokenizer, code: Code) -> State { let container = tokenizer.container.as_mut().unwrap(); let size = container.size; @@ -378,13 +378,13 @@ pub fn not_blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } /// A state fn to yield [`State::Ok`]. -pub fn ok(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) +pub fn ok(_tokenizer: &mut Tokenizer, code: Code) -> State { + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } /// A state fn to yield [`State::Nok`]. -fn nok(_tokenizer: &mut Tokenizer, _code: Code) -> StateFnResult { - (State::Nok, 0) +fn nok(_tokenizer: &mut Tokenizer, _code: Code) -> State { + State::Nok } /// Find adjacent list items with the same marker. @@ -437,7 +437,7 @@ pub fn resolve_list_item(tokenizer: &mut Tokenizer, map: &mut EditMap) -> bool { if !matched { let mut index = lists_wip.len(); - let mut exit: Option<usize> = None; + let mut exit = None; while index > 0 { index -= 1; diff --git a/src/construct/paragraph.rs b/src/construct/paragraph.rs index e43ee43..811bc75 100644 --- a/src/construct/paragraph.rs +++ b/src/construct/paragraph.rs @@ -33,7 +33,7 @@ //! [html]: https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element use crate::token::Token; -use crate::tokenizer::{Code, ContentType, EventType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, EventType, State, Tokenizer}; use crate::util::{edit_map::EditMap, skip::opt as skip_opt}; /// Before a paragraph. @@ -42,7 +42,7 @@ use crate::util::{edit_map::EditMap, skip::opt as skip_opt}; /// > | abc /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { unreachable!("unexpected eol/eof") @@ -61,7 +61,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | abc /// ^^^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.exit(Token::Data); @@ -69,11 +69,11 @@ fn inside(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.register_resolver_before("paragraph".to_string(), Box::new(resolve)); // You’d be interrupting. tokenizer.interrupt = true; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(inside)), 0) + State::Fn(Box::new(inside)) } } } diff --git a/src/construct/partial_data.rs b/src/construct/partial_data.rs index 3701e40..11064e6 100644 --- a/src/construct/partial_data.rs +++ b/src/construct/partial_data.rs @@ -7,7 +7,7 @@ //! [text]: crate::content::text use crate::token::Token; -use crate::tokenizer::{Code, EventType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, EventType, State, Tokenizer}; use crate::util::edit_map::EditMap; /// At the beginning of data. @@ -16,11 +16,11 @@ use crate::util::edit_map::EditMap; /// > | abc /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> State { if stop.contains(&code) { tokenizer.enter(Token::Data); tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| data(t, c, stop))), 0) + State::Fn(Box::new(move |t, c| data(t, c, stop))) } else { at_break(tokenizer, code, stop) } @@ -32,18 +32,18 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> St /// > | abc /// ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(move |t, c| at_break(t, c, stop))), 0) + State::Fn(Box::new(move |t, c| at_break(t, c, stop))) } _ if stop.contains(&code) => { tokenizer.register_resolver("data".to_string(), Box::new(resolve_data)); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } _ => { tokenizer.enter(Token::Data); @@ -58,7 +58,7 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> Sta /// > | abc /// ^^^ /// ``` -fn data(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> StateFnResult { +fn data(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> State { let done = match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => true, _ if stop.contains(&code) => true, @@ -70,7 +70,7 @@ fn data(tokenizer: &mut Tokenizer, code: Code, stop: &'static [Code]) -> StateFn at_break(tokenizer, code, stop) } else { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| data(t, c, stop))), 0) + State::Fn(Box::new(move |t, c| data(t, c, stop))) } } diff --git a/src/construct/partial_destination.rs b/src/construct/partial_destination.rs index de2952c..f898eb5 100644 --- a/src/construct/partial_destination.rs +++ b/src/construct/partial_destination.rs @@ -72,7 +72,7 @@ //! [sanitize_uri]: crate::util::sanitize_uri use crate::token::Token; -use crate::tokenizer::{Code, ContentType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, State, Tokenizer}; /// Configuration. /// @@ -110,7 +110,7 @@ struct Info { /// > | aa /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> State { let info = Info { balance: 0, options, @@ -123,12 +123,12 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn tokenizer.enter(info.options.marker.clone()); tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); - (State::Fn(Box::new(|t, c| enclosed_before(t, c, info))), 0) + State::Fn(Box::new(|t, c| enclosed_before(t, c, info))) } Code::None | Code::CarriageReturnLineFeed | Code::VirtualSpace | Code::Char(' ' | ')') => { - (State::Nok, 0) + State::Nok } - Code::Char(char) if char.is_ascii_control() => (State::Nok, 0), + Code::Char(char) if char.is_ascii_control() => State::Nok, Code::Char(_) => { tokenizer.enter(info.options.destination.clone()); tokenizer.enter(info.options.raw.clone()); @@ -145,14 +145,14 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn /// > | <aa> /// ^ /// ``` -fn enclosed_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn enclosed_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { if let Code::Char('>') = code { tokenizer.enter(info.options.marker.clone()); tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); tokenizer.exit(info.options.literal.clone()); tokenizer.exit(info.options.destination); - (State::Ok, 0) + State::Ok(0) } else { tokenizer.enter(info.options.string.clone()); tokenizer.enter_with_content(Token::Data, Some(ContentType::String)); @@ -166,23 +166,21 @@ fn enclosed_before(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFn /// > | <aa> /// ^ /// ``` -fn enclosed(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn enclosed(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('>') => { tokenizer.exit(Token::Data); tokenizer.exit(info.options.string.clone()); enclosed_before(tokenizer, code, info) } - Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r' | '<') => { - (State::Nok, 0) - } + Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r' | '<') => State::Nok, Code::Char('\\') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| enclosed_escape(t, c, info))), 0) + State::Fn(Box::new(|t, c| enclosed_escape(t, c, info))) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| enclosed(t, c, info))), 0) + State::Fn(Box::new(|t, c| enclosed(t, c, info))) } } } @@ -193,11 +191,11 @@ fn enclosed(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult /// > | <a\*a> /// ^ /// ``` -fn enclosed_escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn enclosed_escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('<' | '>' | '\\') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| enclosed(t, c, info))), 0) + State::Fn(Box::new(|t, c| enclosed(t, c, info))) } _ => enclosed(tokenizer, code, info), } @@ -209,15 +207,15 @@ fn enclosed_escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFn /// > | aa /// ^ /// ``` -fn raw(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn raw(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char('(') => { if info.balance >= info.options.limit { - (State::Nok, 0) + State::Nok } else { tokenizer.consume(code); info.balance += 1; - (State::Fn(Box::new(move |t, c| raw(t, c, info))), 0) + State::Fn(Box::new(move |t, c| raw(t, c, info))) } } Code::Char(')') => { @@ -226,11 +224,11 @@ fn raw(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { tokenizer.exit(info.options.string.clone()); tokenizer.exit(info.options.raw.clone()); tokenizer.exit(info.options.destination); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } else { tokenizer.consume(code); info.balance -= 1; - (State::Fn(Box::new(move |t, c| raw(t, c, info))), 0) + State::Fn(Box::new(move |t, c| raw(t, c, info))) } } Code::None @@ -238,23 +236,23 @@ fn raw(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { | Code::VirtualSpace | Code::Char('\t' | '\n' | '\r' | ' ') => { if info.balance > 0 { - (State::Nok, 0) + State::Nok } else { tokenizer.exit(Token::Data); tokenizer.exit(info.options.string.clone()); tokenizer.exit(info.options.raw.clone()); tokenizer.exit(info.options.destination); - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } - Code::Char(char) if char.is_ascii_control() => (State::Nok, 0), + Code::Char(char) if char.is_ascii_control() => State::Nok, Code::Char('\\') => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| raw_escape(t, c, info))), 0) + State::Fn(Box::new(move |t, c| raw_escape(t, c, info))) } Code::Char(_) => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| raw(t, c, info))), 0) + State::Fn(Box::new(move |t, c| raw(t, c, info))) } } } @@ -265,11 +263,11 @@ fn raw(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { /// > | a\*a /// ^ /// ``` -fn raw_escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn raw_escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char('(' | ')' | '\\') => { tokenizer.consume(code); - (State::Fn(Box::new(move |t, c| raw(t, c, info))), 0) + State::Fn(Box::new(move |t, c| raw(t, c, info))) } _ => raw(tokenizer, code, info), } diff --git a/src/construct/partial_label.rs b/src/construct/partial_label.rs index 0892dbd..d2219cd 100644 --- a/src/construct/partial_label.rs +++ b/src/construct/partial_label.rs @@ -62,7 +62,7 @@ use super::partial_space_or_tab::{space_or_tab_eol_with_options, EolOptions}; use crate::constant::LINK_REFERENCE_SIZE_MAX; use crate::subtokenize::link; use crate::token::Token; -use crate::tokenizer::{Code, ContentType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, State, Tokenizer}; /// Configuration. /// @@ -96,7 +96,7 @@ struct Info { /// > | [a] /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> State { match code { Code::Char('[') => { let info = Info { @@ -110,9 +110,9 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); tokenizer.enter(info.options.string.clone()); - (State::Fn(Box::new(|t, c| at_break(t, c, info))), 0) + State::Fn(Box::new(|t, c| at_break(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -122,18 +122,18 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn /// > | [a] /// ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { - Code::None | Code::Char('[') => (State::Nok, 0), - Code::Char(']') if !info.data => (State::Nok, 0), - _ if info.size > LINK_REFERENCE_SIZE_MAX => (State::Nok, 0), + Code::None | Code::Char('[') => State::Nok, + Code::Char(']') if !info.data => State::Nok, + _ if info.size > LINK_REFERENCE_SIZE_MAX => State::Nok, Code::Char(']') => { tokenizer.exit(info.options.string.clone()); tokenizer.enter(info.options.marker.clone()); tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); tokenizer.exit(info.options.label); - (State::Ok, 0) + State::Ok(0) } Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => tokenizer.go( space_or_tab_eol_with_options(EolOptions { @@ -166,7 +166,7 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes /// > | [a] /// ^ /// ``` -fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r' | '[' | ']') => { tokenizer.exit(Token::Data); @@ -179,7 +179,7 @@ fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult Code::VirtualSpace | Code::Char('\t' | ' ') => { tokenizer.consume(code); info.size += 1; - (State::Fn(Box::new(|t, c| label(t, c, info))), 0) + State::Fn(Box::new(|t, c| label(t, c, info))) } Code::Char('\\') => { tokenizer.consume(code); @@ -187,7 +187,7 @@ fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult if !info.data { info.data = true; } - (State::Fn(Box::new(|t, c| escape(t, c, info))), 0) + State::Fn(Box::new(|t, c| escape(t, c, info))) } Code::Char(_) => { tokenizer.consume(code); @@ -195,7 +195,7 @@ fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult if !info.data { info.data = true; } - (State::Fn(Box::new(|t, c| label(t, c, info))), 0) + State::Fn(Box::new(|t, c| label(t, c, info))) } } } @@ -206,12 +206,12 @@ fn label(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult /// > | [a\*a] /// ^ /// ``` -fn escape(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn escape(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char('[' | '\\' | ']') => { tokenizer.consume(code); info.size += 1; - (State::Fn(Box::new(|t, c| label(t, c, info))), 0) + State::Fn(Box::new(|t, c| label(t, c, info))) } _ => label(tokenizer, code, info), } diff --git a/src/construct/partial_non_lazy_continuation.rs b/src/construct/partial_non_lazy_continuation.rs index c3b82c7..c6ac493 100644 --- a/src/construct/partial_non_lazy_continuation.rs +++ b/src/construct/partial_non_lazy_continuation.rs @@ -11,7 +11,7 @@ //! [html_flow]: crate::construct::html_flow use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Start of continuation. /// @@ -20,15 +20,15 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// ^ /// | b /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(after)), 0) + State::Fn(Box::new(after)) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -39,10 +39,10 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | b /// ^ /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { if tokenizer.lazy { - (State::Nok, 0) + State::Nok } else { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } diff --git a/src/construct/partial_space_or_tab.rs b/src/construct/partial_space_or_tab.rs index aacf28c..6eb3f1d 100644 --- a/src/construct/partial_space_or_tab.rs +++ b/src/construct/partial_space_or_tab.rs @@ -6,7 +6,7 @@ use crate::subtokenize::link; use crate::token::Token; -use crate::tokenizer::{Code, ContentType, State, StateFn, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, State, StateFn, Tokenizer}; /// Options to parse `space_or_tab`. #[derive(Debug)] @@ -132,7 +132,7 @@ pub fn space_or_tab_eol_with_options(options: EolOptions) -> Box<StateFn> { /// > | a␠␠b /// ^ /// ``` -fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ') if info.options.max > 0 => { tokenizer @@ -145,13 +145,13 @@ fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult tokenizer.consume(code); info.size += 1; - (State::Fn(Box::new(|t, c| inside(t, c, info))), 0) + State::Fn(Box::new(|t, c| inside(t, c, info))) } _ => { if info.options.min == 0 { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } else { - (State::Nok, 0) + State::Nok } } } @@ -163,19 +163,19 @@ fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult /// > | a␠␠b /// ^ /// ``` -fn inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::VirtualSpace | Code::Char('\t' | ' ') if info.size < info.options.max => { tokenizer.consume(code); info.size += 1; - (State::Fn(Box::new(|t, c| inside(t, c, info))), 0) + State::Fn(Box::new(|t, c| inside(t, c, info))) } _ => { tokenizer.exit(info.options.kind.clone()); if info.size >= info.options.min { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } else { - (State::Nok, 0) + State::Nok } } } @@ -188,7 +188,7 @@ fn inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResul /// ^ /// | b /// ``` -fn after_space_or_tab(tokenizer: &mut Tokenizer, code: Code, mut info: EolInfo) -> StateFnResult { +fn after_space_or_tab(tokenizer: &mut Tokenizer, code: Code, mut info: EolInfo) -> State { match code { Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter_with_content(Token::LineEnding, info.options.content_type.clone()); @@ -202,10 +202,10 @@ fn after_space_or_tab(tokenizer: &mut Tokenizer, code: Code, mut info: EolInfo) tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(|t, c| after_eol(t, c, info))), 0) + State::Fn(Box::new(|t, c| after_eol(t, c, info))) } - _ if info.ok => (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }), - _ => (State::Nok, 0), + _ if info.ok => State::Ok(if matches!(code, Code::None) { 0 } else { 1 }), + _ => State::Nok, } } @@ -217,7 +217,7 @@ fn after_space_or_tab(tokenizer: &mut Tokenizer, code: Code, mut info: EolInfo) /// ^ /// ``` #[allow(clippy::needless_pass_by_value)] -fn after_eol(tokenizer: &mut Tokenizer, code: Code, info: EolInfo) -> StateFnResult { +fn after_eol(tokenizer: &mut Tokenizer, code: Code, info: EolInfo) -> State { tokenizer.attempt_opt( space_or_tab_with_options(Options { kind: Token::SpaceOrTab, @@ -237,14 +237,14 @@ fn after_eol(tokenizer: &mut Tokenizer, code: Code, info: EolInfo) -> StateFnRes /// > | b /// ^ /// ``` -fn after_more_space_or_tab(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after_more_space_or_tab(_tokenizer: &mut Tokenizer, code: Code) -> State { // Blank line not allowed. if matches!( code, Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') ) { - (State::Nok, 0) + State::Nok } else { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } } diff --git a/src/construct/partial_title.rs b/src/construct/partial_title.rs index f69d609..8510391 100644 --- a/src/construct/partial_title.rs +++ b/src/construct/partial_title.rs @@ -33,7 +33,7 @@ use super::partial_space_or_tab::{space_or_tab_eol_with_options, EolOptions}; use crate::subtokenize::link; use crate::token::Token; -use crate::tokenizer::{Code, ContentType, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, ContentType, State, Tokenizer}; /// Configuration. /// @@ -135,7 +135,7 @@ struct Info { /// > | "a" /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> State { match code { Code::Char('"' | '\'' | '(') => { let info = Info { @@ -147,9 +147,9 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn tokenizer.enter(info.options.marker.clone()); tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); - (State::Fn(Box::new(|t, c| begin(t, c, info))), 0) + State::Fn(Box::new(|t, c| begin(t, c, info))) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -161,14 +161,14 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn /// > | "a" /// ^ /// ``` -fn begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.enter(info.options.marker.clone()); tokenizer.consume(code); tokenizer.exit(info.options.marker.clone()); tokenizer.exit(info.options.title); - (State::Ok, 0) + State::Ok(0) } _ => { tokenizer.enter(info.options.string.clone()); @@ -183,13 +183,13 @@ fn begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { /// > | "a" /// ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.exit(info.options.string.clone()); begin(tokenizer, code, info) } - Code::None => (State::Nok, 0), + Code::None => State::Nok, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => tokenizer.go( space_or_tab_eol_with_options(EolOptions { content_type: Some(ContentType::String), @@ -221,7 +221,7 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes /// > | "a" /// ^ /// ``` -fn title(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn title(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.exit(Token::Data); @@ -233,11 +233,11 @@ fn title(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { } Code::Char('\\') => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| escape(t, c, info))), 0) + State::Fn(Box::new(|t, c| escape(t, c, info))) } _ => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| title(t, c, info))), 0) + State::Fn(Box::new(|t, c| title(t, c, info))) } } } @@ -248,11 +248,11 @@ fn title(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { /// > | "a\*b" /// ^ /// ``` -fn escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn escape(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.consume(code); - (State::Fn(Box::new(|t, c| title(t, c, info))), 0) + State::Fn(Box::new(|t, c| title(t, c, info))) } _ => title(tokenizer, code, info), } diff --git a/src/construct/partial_whitespace.rs b/src/construct/partial_whitespace.rs index 7624ec0..4fc013e 100644 --- a/src/construct/partial_whitespace.rs +++ b/src/construct/partial_whitespace.rs @@ -24,10 +24,10 @@ //! [space_or_tab_eol]: crate::construct::partial_space_or_tab::space_or_tab_eol use super::partial_space_or_tab::space_or_tab; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Parse initial or final whitespace. -pub fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go( // Nothing if there’s no whitespace. space_or_tab(), @@ -45,18 +45,18 @@ pub fn whitespace(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } /// After whitespace, at an eol/eof. -fn at_eol(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn at_eol(tokenizer: &mut Tokenizer, code: Code) -> State { if matches!( code, Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') ) { ok(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } /// Fine. -fn ok(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) +fn ok(_tokenizer: &mut Tokenizer, code: Code) -> State { + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } diff --git a/src/construct/thematic_break.rs b/src/construct/thematic_break.rs index d87778f..4159146 100644 --- a/src/construct/thematic_break.rs +++ b/src/construct/thematic_break.rs @@ -51,7 +51,7 @@ use super::partial_space_or_tab::{space_or_tab, space_or_tab_min_max}; use crate::constant::{TAB_SIZE, THEMATIC_BREAK_MARKER_COUNT_MIN}; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Type of thematic break. #[derive(Debug, PartialEq)] @@ -134,7 +134,7 @@ struct Info { /// > | *** /// ^ /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let max = if tokenizer.parse_state.constructs.code_indented { TAB_SIZE - 1 } else { @@ -145,7 +145,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::ThematicBreak); tokenizer.go(space_or_tab_min_max(0, max), before)(tokenizer, code) } else { - (State::Nok, 0) + State::Nok } } @@ -155,7 +155,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | *** /// ^ /// ``` -fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { Code::Char('*' | '-' | '_') => at_break( tokenizer, @@ -165,7 +165,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { size: 0, }, ), - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -175,7 +175,7 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | *** /// ^ /// ``` -fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { +fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> State { match code { Code::None | Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') if info.size >= THEMATIC_BREAK_MARKER_COUNT_MIN => @@ -183,13 +183,13 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult tokenizer.exit(Token::ThematicBreak); // Feel free to interrupt. tokenizer.interrupt = false; - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + State::Ok(if matches!(code, Code::None) { 0 } else { 1 }) } Code::Char(char) if char == info.kind.as_char() => { tokenizer.enter(Token::ThematicBreakSequence); sequence(tokenizer, code, info) } - _ => (State::Nok, 0), + _ => State::Nok, } } @@ -199,12 +199,12 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult /// > | *** /// ^ /// ``` -fn sequence(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult { +fn sequence(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> State { match code { Code::Char(char) if char == info.kind.as_char() => { tokenizer.consume(code); info.size += 1; - (State::Fn(Box::new(|t, c| sequence(t, c, info))), 0) + State::Fn(Box::new(|t, c| sequence(t, c, info))) } _ => { tokenizer.exit(Token::ThematicBreakSequence); diff --git a/src/content/document.rs b/src/content/document.rs index 163dcda..f2c73e4 100644 --- a/src/content/document.rs +++ b/src/content/document.rs @@ -17,8 +17,7 @@ use crate::parser::ParseState; use crate::subtokenize::subtokenize; use crate::token::Token; use crate::tokenizer::{ - Code, Container, ContainerState, Event, EventType, Point, State, StateFn, StateFnResult, - Tokenizer, + Code, Container, ContainerState, Event, EventType, Point, State, StateFn, Tokenizer, }; use crate::util::edit_map::EditMap; use crate::util::{ @@ -122,7 +121,7 @@ pub fn document(parse_state: &mut ParseState, point: Point) -> Vec<Event> { /// ^ /// | > b /// ``` -fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn start(tokenizer: &mut Tokenizer, code: Code) -> State { let info = DocumentInfo { index: 0, continued: 0, @@ -143,7 +142,7 @@ fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// > | > b /// ^ /// ``` -fn line_start(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo) -> StateFnResult { +fn line_start(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo) -> State { info.index = tokenizer.events.len(); info.inject.push((vec![], vec![])); info.continued = 0; @@ -163,7 +162,7 @@ fn container_existing_before( tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo, -) -> StateFnResult { +) -> State { // If there are more existing containers, check whether the next one continues. if info.continued < info.stack.len() { let container = info.stack.remove(info.continued); @@ -198,7 +197,7 @@ fn container_existing_missing( tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo, -) -> StateFnResult { +) -> State { let container = tokenizer.container.take().unwrap(); info.stack.insert(info.continued, container); container_new_before(tokenizer, code, info) @@ -215,7 +214,7 @@ fn container_existing_after( tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo, -) -> StateFnResult { +) -> State { let container = tokenizer.container.take().unwrap(); info.stack.insert(info.continued, container); info.continued += 1; @@ -230,11 +229,7 @@ fn container_existing_after( /// > | > b /// ^ /// ``` -fn container_new_before( - tokenizer: &mut Tokenizer, - code: Code, - info: DocumentInfo, -) -> StateFnResult { +fn container_new_before(tokenizer: &mut Tokenizer, code: Code, info: DocumentInfo) -> State { // If we have completely continued, restore the flow’s past `interrupt` // status. if info.continued == info.stack.len() { @@ -288,11 +283,7 @@ fn container_new_before( /// > | > b /// ^ /// ``` -fn container_new_after( - tokenizer: &mut Tokenizer, - code: Code, - mut info: DocumentInfo, -) -> StateFnResult { +fn container_new_after(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo) -> State { let container = tokenizer.container.take().unwrap(); // Remove from the event stack. @@ -340,11 +331,7 @@ fn container_new_after( /// > | > b /// ^ /// ``` -fn containers_after( - tokenizer: &mut Tokenizer, - code: Code, - mut info: DocumentInfo, -) -> StateFnResult { +fn containers_after(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo) -> State { // Store the container events we parsed. info.inject .last_mut() @@ -363,12 +350,7 @@ fn containers_after( tokenizer.go_until( state, |code| matches!(code, Code::CarriageReturnLineFeed | Code::Char('\n' | '\r')), - move |(state, back)| { - ( - State::Fn(Box::new(move |t, c| flow_end(t, c, info, state))), - back, - ) - }, + move |state| Box::new(move |t, c| flow_end(t, c, info, state)), )(tokenizer, code) } @@ -379,12 +361,7 @@ fn containers_after( /// > | > b /// ^ ^ /// ``` -fn flow_end( - tokenizer: &mut Tokenizer, - code: Code, - mut info: DocumentInfo, - result: State, -) -> StateFnResult { +fn flow_end(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo, result: State) -> State { let paragraph = !tokenizer.events.is_empty() && tokenizer.events[skip::opt_back( &tokenizer.events, @@ -407,15 +384,16 @@ fn flow_end( info.interrupt_before = tokenizer.interrupt; match result { - State::Ok => { + State::Ok(back) => { + assert_eq!(back, 0); + if !info.stack.is_empty() { info.continued = 0; info = exit_containers(tokenizer, info, &Phase::Eof); } resolve(tokenizer, &mut info); - - (State::Ok, if matches!(code, Code::None) { 0 } else { 1 }) + result } State::Nok => unreachable!("unexpected `nok` from flow"), State::Fn(func) => { @@ -440,8 +418,7 @@ fn exit_containers( let next = info.next; info.next = Box::new(flow); // This is weird but Rust needs a function there. let result = tokenizer.flush(next); - assert!(matches!(result.0, State::Ok)); - assert_eq!(result.1, 0); + assert!(matches!(result, State::Ok(0))); if *phase == Phase::Prefix { info.index = tokenizer.events.len(); @@ -481,7 +458,7 @@ fn resolve(tokenizer: &mut Tokenizer, info: &mut DocumentInfo) { let mut index = 0; let mut inject = info.inject.split_off(0); inject.reverse(); - let mut first_line_ending_in_run: Option<usize> = None; + let mut first_line_ending_in_run = None; while let Some((before, mut after)) = inject.pop() { if !before.is_empty() { diff --git a/src/content/flow.rs b/src/content/flow.rs index 722e2bb..8aed92b 100644 --- a/src/content/flow.rs +++ b/src/content/flow.rs @@ -27,7 +27,7 @@ use crate::construct::{ thematic_break::start as thematic_break, }; use crate::token::Token; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; /// Before flow. /// @@ -39,9 +39,9 @@ use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; /// | bravo /// |*** /// ``` -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), _ => tokenizer.attempt(blank_line, |ok| { Box::new(if ok { blank_line_after } else { initial_before }) })(tokenizer, code), @@ -60,9 +60,9 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// |~~~js /// |<div> /// ``` -fn initial_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn initial_before(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), _ => tokenizer.attempt_n( vec![ Box::new(code_indented), @@ -85,16 +85,16 @@ fn initial_before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ```markdown /// ␠␠| /// ``` -fn blank_line_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn blank_line_after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::BlankLineEnding); tokenizer.consume(code); tokenizer.exit(Token::BlankLineEnding); // Feel free to interrupt. tokenizer.interrupt = false; - (State::Fn(Box::new(start)), 0) + State::Fn(Box::new(start)) } _ => unreachable!("expected eol/eof"), } @@ -109,14 +109,14 @@ fn blank_line_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// asd /// ~~~| /// ``` -fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn after(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), Code::CarriageReturnLineFeed | Code::Char('\n' | '\r') => { tokenizer.enter(Token::LineEnding); tokenizer.consume(code); tokenizer.exit(Token::LineEnding); - (State::Fn(Box::new(start)), 0) + State::Fn(Box::new(start)) } _ => unreachable!("expected eol/eof"), } @@ -127,6 +127,6 @@ fn after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ```markdown /// |asd /// ``` -fn before_paragraph(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before_paragraph(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go(paragraph, after)(tokenizer, code) } diff --git a/src/content/string.rs b/src/content/string.rs index f63b8be..fad2b6a 100644 --- a/src/content/string.rs +++ b/src/content/string.rs @@ -16,7 +16,7 @@ use crate::construct::{ character_escape::start as character_escape, character_reference::start as character_reference, partial_data::start as data, partial_whitespace::whitespace, }; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; const MARKERS: [Code; 5] = [ Code::VirtualSpace, // `whitespace` @@ -27,9 +27,9 @@ const MARKERS: [Code; 5] = [ ]; /// Before string. -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), _ => tokenizer.attempt_n( vec![ Box::new(character_reference), @@ -45,6 +45,6 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } /// At data. -fn before_data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before_data(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go(|t, c| data(t, c, &MARKERS), start)(tokenizer, code) } diff --git a/src/content/text.rs b/src/content/text.rs index c339324..0d90cb4 100644 --- a/src/content/text.rs +++ b/src/content/text.rs @@ -27,7 +27,7 @@ use crate::construct::{ label_start_link::start as label_start_link, partial_data::start as data, partial_whitespace::whitespace, }; -use crate::tokenizer::{Code, State, StateFnResult, Tokenizer}; +use crate::tokenizer::{Code, State, Tokenizer}; const MARKERS: [Code; 12] = [ Code::VirtualSpace, // `whitespace` @@ -45,9 +45,9 @@ const MARKERS: [Code; 12] = [ ]; /// Before text. -pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +pub fn start(tokenizer: &mut Tokenizer, code: Code) -> State { match code { - Code::None => (State::Ok, 0), + Code::None => State::Ok(0), _ => tokenizer.attempt_n( vec![ Box::new(attention), @@ -76,6 +76,6 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { /// ```markdown /// |qwe /// ``` -fn before_data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { +fn before_data(tokenizer: &mut Tokenizer, code: Code) -> State { tokenizer.go(|t, c| data(t, c, &MARKERS), start)(tokenizer, code) } diff --git a/src/subtokenize.rs b/src/subtokenize.rs index ad6f53f..2b5d775 100644 --- a/src/subtokenize.rs +++ b/src/subtokenize.rs @@ -23,7 +23,7 @@ use crate::content::{string::start as string, text::start as text}; use crate::parser::ParseState; -use crate::tokenizer::{ContentType, Event, EventType, State, StateFn, StateFnResult, Tokenizer}; +use crate::tokenizer::{ContentType, Event, EventType, State, Tokenizer}; use crate::util::{edit_map::EditMap, span}; /// Create a link between two [`Event`][]s. @@ -75,18 +75,15 @@ pub fn subtokenize(events: &mut Vec<Event>, parse_state: &ParseState) -> bool { // No need to enter linked events again. if link.previous == None { // Index into `events` pointing to a chunk. - let mut link_index: Option<usize> = Some(index); + let mut link_index = Some(index); // Subtokenizer. let mut tokenizer = Tokenizer::new(event.point.clone(), parse_state); // Substate. - let mut result: StateFnResult = ( - State::Fn(Box::new(if link.content_type == ContentType::String { - string - } else { - text - })), - 0, - ); + let mut state = State::Fn(Box::new(if link.content_type == ContentType::String { + string + } else { + text + })); // Loop through links to pass them in order to the subtokenizer. while let Some(index) = link_index { @@ -102,17 +99,16 @@ pub fn subtokenize(events: &mut Vec<Event>, parse_state: &ParseState) -> bool { tokenizer.define_skip(&enter.point); } - let func: Box<StateFn> = match result.0 { + let func = match state { State::Fn(func) => func, _ => unreachable!("cannot be ok/nok"), }; - result = tokenizer.push( + state = tokenizer.push( span::codes(&parse_state.codes, &span), func, link_curr.next == None, ); - assert_eq!(result.1, 0, "expected no remainder"); link_index = link_curr.next; } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 544e8b0..85a2155 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -87,12 +87,8 @@ pub struct Event { /// The essence of the state machine are functions: `StateFn`. /// It’s responsible for dealing with that single passed [`Code`][]. -/// It yields a [`StateFnResult`][]. -pub type StateFn = dyn FnOnce(&mut Tokenizer, Code) -> StateFnResult; - -/// Each [`StateFn`][] yields something back: primarily the state. -/// In certain cases, it can also yield back up parsed codes that were passed down. -pub type StateFnResult = (State, usize); +/// It yields a [`State`][]. +pub type StateFn = dyn FnOnce(&mut Tokenizer, Code) -> State; /// Callback that can be registered and is called when the tokenizer is done. /// @@ -106,7 +102,7 @@ pub enum State { /// There is a future state: a boxed [`StateFn`][] to pass the next code to. Fn(Box<StateFn>), /// The state is successful. - Ok, + Ok(usize), /// The state is not successful. Nok, } @@ -472,18 +468,18 @@ impl<'a> Tokenizer<'a> { #[allow(clippy::unused_self)] pub fn go( &mut self, - state_fn: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, - after: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state_fn: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, + after: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, ) -> Box<StateFn> { attempt_impl( state_fn, |_code| false, vec![], |result: (Vec<Code>, Vec<Code>), tokenizer: &mut Tokenizer, state| { - if matches!(state, State::Ok) { + if matches!(state, State::Ok(_)) { feed_impl(tokenizer, &result.1, after) } else { - (State::Nok, 0) + State::Nok } }, ) @@ -494,9 +490,9 @@ impl<'a> Tokenizer<'a> { #[allow(clippy::unused_self)] pub fn go_until( &mut self, - state_fn: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state_fn: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, until: impl FnMut(Code) -> bool + 'static, - done: impl FnOnce(StateFnResult) -> StateFnResult + 'static, + done: impl FnOnce(State) -> Box<StateFn> + 'static, ) -> Box<StateFn> { attempt_impl( state_fn, @@ -504,7 +500,7 @@ impl<'a> Tokenizer<'a> { vec![], |result: (Vec<Code>, Vec<Code>), tokenizer: &mut Tokenizer, state| { tokenizer.consumed = true; - done((state, result.1.len())) + feed_impl(tokenizer, &result.1, done(state)) }, ) } @@ -520,7 +516,7 @@ impl<'a> Tokenizer<'a> { /// captured codes to its future states. pub fn check( &mut self, - state_fn: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state_fn: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, done: impl FnOnce(bool) -> Box<StateFn> + 'static, ) -> Box<StateFn> { let previous = self.capture(); @@ -532,7 +528,7 @@ impl<'a> Tokenizer<'a> { |mut result: (Vec<Code>, Vec<Code>), tokenizer: &mut Tokenizer, state| { tokenizer.free(previous); result.0.append(&mut result.1); - feed_impl(tokenizer, &result.0, done(matches!(state, State::Ok))) + feed_impl(tokenizer, &result.0, done(matches!(state, State::Ok(_)))) }, ) } @@ -550,7 +546,7 @@ impl<'a> Tokenizer<'a> { /// `done` is called, and all captured codes are fed to its future states. pub fn attempt( &mut self, - state_fn: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state_fn: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, done: impl FnOnce(bool) -> Box<StateFn> + 'static, ) -> Box<StateFn> { let previous = self.capture(); @@ -560,7 +556,7 @@ impl<'a> Tokenizer<'a> { |_code| false, vec![], |mut result: (Vec<Code>, Vec<Code>), tokenizer: &mut Tokenizer, state| { - let ok = matches!(state, State::Ok); + let ok = matches!(state, State::Ok(_)); if !ok { tokenizer.free(previous); @@ -609,8 +605,8 @@ impl<'a> Tokenizer<'a> { /// about `ok`. pub fn attempt_opt( &mut self, - state_fn: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, - after: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state_fn: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, + after: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, ) -> Box<StateFn> { self.attempt(state_fn, |_ok| Box::new(after)) } @@ -622,15 +618,15 @@ impl<'a> Tokenizer<'a> { pub fn push( &mut self, codes: &[Code], - start: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + start: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, drain: bool, - ) -> StateFnResult { + ) -> State { assert!(!self.drained, "cannot feed after drain"); let mut result = feed_impl(self, codes, start); if drain { - let func = match result.0 { + let func = match result { State::Fn(func) => func, _ => unreachable!("expected next state"), }; @@ -663,10 +659,7 @@ impl<'a> Tokenizer<'a> { } /// Flush the tokenizer. - pub fn flush( - &mut self, - start: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, - ) -> StateFnResult { + pub fn flush(&mut self, start: impl FnOnce(&mut Tokenizer, Code) -> State + 'static) -> State { flush_impl(self, start) } } @@ -676,10 +669,10 @@ impl<'a> Tokenizer<'a> { /// Recurses into itself. /// Used in [`Tokenizer::attempt`][Tokenizer::attempt] and [`Tokenizer::check`][Tokenizer::check]. fn attempt_impl( - state: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, + state: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, mut pause: impl FnMut(Code) -> bool + 'static, mut codes: Vec<Code>, - done: impl FnOnce((Vec<Code>, Vec<Code>), &mut Tokenizer, State) -> StateFnResult + 'static, + done: impl FnOnce((Vec<Code>, Vec<Code>), &mut Tokenizer, State) -> State + 'static, ) -> Box<StateFn> { Box::new(|tokenizer, code| { if !codes.is_empty() && pause(tokenizer.previous) { @@ -688,10 +681,11 @@ fn attempt_impl( } else { vec![code] }; + return done((codes, after), tokenizer, State::Fn(Box::new(state))); } - let (next, back) = state(tokenizer, code); + let state = state(tokenizer, code); match code { Code::None => {} @@ -700,20 +694,17 @@ fn attempt_impl( } } - assert!( - back <= codes.len(), - "`back` must be smaller than or equal to `codes.len()`" - ); - - match next { - State::Ok | State::Nok => { + match state { + State::Ok(back) => { + assert!( + back <= codes.len(), + "`back` must be smaller than or equal to `codes.len()`" + ); let remaining = codes.split_off(codes.len() - back); - done((codes, remaining), tokenizer, next) - } - State::Fn(func) => { - assert_eq!(back, 0, "expected no remainder"); - (State::Fn(attempt_impl(func, pause, codes, done)), 0) + done((codes, remaining), tokenizer, state) } + State::Nok => done((vec![], codes), tokenizer, state), + State::Fn(func) => State::Fn(attempt_impl(func, pause, codes, done)), } }) } @@ -722,8 +713,8 @@ fn attempt_impl( fn feed_impl( tokenizer: &mut Tokenizer, codes: &[Code], - start: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, -) -> StateFnResult { + start: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, +) -> State { let mut state = State::Fn(Box::new(start)); let mut index = 0; @@ -733,49 +724,48 @@ fn feed_impl( let code = codes[index]; match state { - State::Ok | State::Nok => break, + State::Ok(back) => { + state = State::Ok((codes.len() - index) + back); + break; + } + State::Nok => break, State::Fn(func) => { log::debug!("main: passing: `{:?}` ({:?})", code, index); tokenizer.expect(code, false); - let (next, back) = func(tokenizer, code); - state = next; - index = index + 1 - back; + state = func(tokenizer, code); + index += 1; } } } - (state, codes.len() - index) + state } /// Flush `start`: pass `eof`s to it until done. fn flush_impl( tokenizer: &mut Tokenizer, - start: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static, -) -> StateFnResult { + start: impl FnOnce(&mut Tokenizer, Code) -> State + 'static, +) -> State { let mut state = State::Fn(Box::new(start)); tokenizer.consumed = true; loop { - // Feed EOF. match state { - State::Ok | State::Nok => break, + State::Ok(_) | State::Nok => break, State::Fn(func) => { - let code = Code::None; log::debug!("main: passing eof"); - tokenizer.expect(code, false); - let (next, remainder) = func(tokenizer, code); - assert_eq!(remainder, 0, "expected no remainder"); - state = next; + tokenizer.expect(Code::None, false); + state = func(tokenizer, Code::None); } } } match state { - State::Ok => {} + State::Ok(back) => assert_eq!(back, 0, "expected final `back` to be `0`"), _ => unreachable!("expected final state to be `State::Ok`"), } - (state, 0) + state } /// Define a jump between two places. diff --git a/src/util/codes.rs b/src/util/codes.rs index d35d7d9..5006a00 100644 --- a/src/util/codes.rs +++ b/src/util/codes.rs @@ -7,7 +7,7 @@ use crate::tokenizer::Code; pub fn parse(value: &str) -> Vec<Code> { // Note: It’ll grow a bit bigger with each `Code::VirtualSpace`, smaller // with `Code::CarriageReturnLineFeed`. - let mut codes: Vec<Code> = Vec::with_capacity(value.len()); + let mut codes = Vec::with_capacity(value.len()); let mut at_start = true; let mut at_carriage_return = false; let mut column = 1; diff --git a/src/util/edit_map.rs b/src/util/edit_map.rs index 38ece01..3bcef48 100644 --- a/src/util/edit_map.rs +++ b/src/util/edit_map.rs @@ -104,7 +104,7 @@ impl EditMap { let len_before = events.len(); let mut index = self.map.len(); - let mut vecs: Vec<Vec<Event>> = Vec::with_capacity(index * 2 + 1); + let mut vecs = Vec::with_capacity(index * 2 + 1); while index > 0 { index -= 1; vecs.push(events.split_off(self.map[index].0 + self.map[index].1)); diff --git a/tests/misc_url.rs b/tests/misc_url.rs index 5e94366..027f9bf 100644 --- a/tests/misc_url.rs +++ b/tests/misc_url.rs @@ -117,7 +117,7 @@ fn url() { "should support an emoji" ); - let mut ascii: Vec<char> = vec![]; + let mut ascii = Vec::with_capacity(129); let mut code = 0; while code < 128 { |