aboutsummaryrefslogtreecommitdiffstats
path: root/src/construct/partial_space_or_tab.rs
diff options
context:
space:
mode:
authorLibravatar Titus Wormer <tituswormer@gmail.com>2022-06-22 15:20:33 +0200
committerLibravatar Titus Wormer <tituswormer@gmail.com>2022-06-22 15:20:33 +0200
commit227e844154d9a592b80a88d7b8731d3d2f2fb3e2 (patch)
tree09d4243db0ae3d51c2420e70b9e364d470d520bd /src/construct/partial_space_or_tab.rs
parent6fdaffb3a8b4517a3b5c1e39dc1e16649c6eb0da (diff)
downloadmarkdown-rs-227e844154d9a592b80a88d7b8731d3d2f2fb3e2.tar.gz
markdown-rs-227e844154d9a592b80a88d7b8731d3d2f2fb3e2.tar.bz2
markdown-rs-227e844154d9a592b80a88d7b8731d3d2f2fb3e2.zip
Add `attempt_opt` to tokenizer
Diffstat (limited to 'src/construct/partial_space_or_tab.rs')
-rw-r--r--src/construct/partial_space_or_tab.rs59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/construct/partial_space_or_tab.rs b/src/construct/partial_space_or_tab.rs
index cbb2cf3..024a4b2 100644
--- a/src/construct/partial_space_or_tab.rs
+++ b/src/construct/partial_space_or_tab.rs
@@ -8,24 +8,31 @@ use crate::tokenizer::{Code, State, StateFn, StateFnResult, TokenType, Tokenizer
/// Options to parse whitespace.
#[derive(Debug)]
-struct Info {
- /// Current size.
- size: usize,
+pub struct Options {
/// Minimum allowed characters (inclusive).
- min: usize,
+ pub min: usize,
/// Maximum allowed characters (inclusive).
- max: usize,
+ pub max: usize,
/// Token type to use for whitespace events.
- kind: TokenType,
+ pub kind: TokenType,
+}
+
+/// Options to parse whitespace.
+#[derive(Debug)]
+struct Info {
+ /// Current size.
+ size: usize,
+ /// Configuration.
+ options: Options,
}
-/// Optional `space_or_tab`
+/// One or more `space_or_tab`.
///
/// ```bnf
-/// space_or_tab_opt ::= *( ' ' '\t' )
+/// space_or_tab ::= 1*( ' ' '\t' )
/// ```
-pub fn space_or_tab_opt() -> Box<StateFn> {
- space_or_tab_min_max(0, usize::MAX)
+pub fn space_or_tab() -> Box<StateFn> {
+ space_or_tab_min_max(1, usize::MAX)
}
/// Between `x` and `y` `space_or_tab`
@@ -34,7 +41,11 @@ pub fn space_or_tab_opt() -> Box<StateFn> {
/// space_or_tab_min_max ::= x*y( ' ' '\t' )
/// ```
pub fn space_or_tab_min_max(min: usize, max: usize) -> Box<StateFn> {
- space_or_tab(TokenType::SpaceOrTab, min, max)
+ space_or_tab_with_options(Options {
+ kind: TokenType::SpaceOrTab,
+ min,
+ max,
+ })
}
/// Between `x` and `y` `space_or_tab`, with the given token type.
@@ -42,14 +53,8 @@ pub fn space_or_tab_min_max(min: usize, max: usize) -> Box<StateFn> {
/// ```bnf
/// space_or_tab ::= x*y( ' ' '\t' )
/// ```
-pub fn space_or_tab(kind: TokenType, min: usize, max: usize) -> Box<StateFn> {
- let info = Info {
- size: 0,
- min,
- max,
- kind,
- };
- Box::new(|t, c| start(t, c, info))
+pub fn space_or_tab_with_options(options: Options) -> Box<StateFn> {
+ Box::new(|t, c| start(t, c, Info { size: 0, options }))
}
/// Before whitespace.
@@ -59,14 +64,18 @@ pub fn space_or_tab(kind: TokenType, min: usize, max: usize) -> Box<StateFn> {
/// ```
fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult {
match code {
- Code::VirtualSpace | Code::Char('\t' | ' ') if info.max > 0 => {
- tokenizer.enter(info.kind.clone());
+ Code::VirtualSpace | Code::Char('\t' | ' ') if info.options.max > 0 => {
+ tokenizer.enter(info.options.kind.clone());
tokenizer.consume(code);
info.size += 1;
(State::Fn(Box::new(|t, c| inside(t, c, info))), None)
}
_ => (
- if info.min == 0 { State::Ok } else { State::Nok },
+ if info.options.min == 0 {
+ State::Ok
+ } else {
+ State::Nok
+ },
Some(vec![code]),
),
}
@@ -80,15 +89,15 @@ fn start(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult
/// ```
fn inside(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnResult {
match code {
- Code::VirtualSpace | Code::Char('\t' | ' ') if info.size < info.max => {
+ 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))), None)
}
_ => {
- tokenizer.exit(info.kind.clone());
+ tokenizer.exit(info.options.kind.clone());
(
- if info.size >= info.min {
+ if info.size >= info.options.min {
State::Ok
} else {
State::Nok