aboutsummaryrefslogtreecommitdiffstats
path: root/src/content
diff options
context:
space:
mode:
authorLibravatar Titus Wormer <tituswormer@gmail.com>2022-07-21 16:08:38 +0200
committerLibravatar Titus Wormer <tituswormer@gmail.com>2022-07-21 16:08:38 +0200
commit1d48e14b70f59bbb3daa5d8dcce176500400965b (patch)
tree66469437725e5eda518c6b23d31caa9910acc345 /src/content
parentc43ad9bfb9467627df1b40266ac7b0d570a55a62 (diff)
downloadmarkdown-rs-1d48e14b70f59bbb3daa5d8dcce176500400965b.tar.gz
markdown-rs-1d48e14b70f59bbb3daa5d8dcce176500400965b.tar.bz2
markdown-rs-1d48e14b70f59bbb3daa5d8dcce176500400965b.zip
Refactor to improve performance by passing markers around
Diffstat (limited to '')
-rw-r--r--src/content/string.rs35
-rw-r--r--src/content/text.rs65
2 files changed, 31 insertions, 69 deletions
diff --git a/src/content/string.rs b/src/content/string.rs
index 0a3f5eb..609a788 100644
--- a/src/content/string.rs
+++ b/src/content/string.rs
@@ -18,26 +18,16 @@ use crate::construct::{
};
use crate::tokenizer::{Code, State, StateFnResult, Tokenizer};
-/// Before string.
-pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
- let mut markers = vec![
- Code::VirtualSpace, // `whitespace`
- Code::Char('\t'), // `whitespace`
- Code::Char(' '), // `hard_break_trailing`, `whitespace`
- ];
-
- if tokenizer.parse_state.constructs.character_reference {
- markers.push(Code::Char('&'));
- }
- if tokenizer.parse_state.constructs.character_escape {
- markers.push(Code::Char('\\'));
- }
-
- before_marker(tokenizer, code, markers)
-}
+const MARKERS: [Code; 5] = [
+ Code::VirtualSpace, // `whitespace`
+ Code::Char('\t'), // `whitespace`
+ Code::Char(' '), // `hard_break_trailing`, `whitespace`
+ Code::Char('&'),
+ Code::Char('\\'),
+];
/// Before string.
-fn before_marker(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> StateFnResult {
+pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
match code {
Code::None => (State::Ok, None),
_ => tokenizer.attempt_n(
@@ -47,15 +37,14 @@ fn before_marker(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> S
Box::new(whitespace),
],
|ok| {
- let func = if ok { before_marker } else { before_data };
- Box::new(move |t, c| func(t, c, markers))
+ let func = if ok { start } else { before_data };
+ Box::new(func)
},
)(tokenizer, code),
}
}
/// At data.
-fn before_data(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> StateFnResult {
- let copy = markers.clone();
- tokenizer.go(|t, c| data(t, c, copy), |t, c| before_marker(t, c, markers))(tokenizer, code)
+fn before_data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
+ tokenizer.go(|t, c| data(t, c, &MARKERS), start)(tokenizer, code)
}
diff --git a/src/content/text.rs b/src/content/text.rs
index 8d63de9..73a798a 100644
--- a/src/content/text.rs
+++ b/src/content/text.rs
@@ -29,49 +29,23 @@ use crate::construct::{
};
use crate::tokenizer::{Code, State, StateFnResult, Tokenizer};
-/// Before text.
-pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
- let mut markers = vec![
- Code::VirtualSpace, // `whitespace`
- Code::Char('\t'), // `whitespace`
- Code::Char(' '), // `hard_break_trailing`, `whitespace`
- ];
-
- if tokenizer.parse_state.constructs.label_start_image {
- markers.push(Code::Char('!'));
- }
- if tokenizer.parse_state.constructs.character_reference {
- markers.push(Code::Char('&'));
- }
- if tokenizer.parse_state.constructs.attention {
- markers.push(Code::Char('*'));
- }
- if tokenizer.parse_state.constructs.autolink || tokenizer.parse_state.constructs.html_text {
- markers.push(Code::Char('<'));
- }
- if tokenizer.parse_state.constructs.label_start_link {
- markers.push(Code::Char('['));
- }
- if tokenizer.parse_state.constructs.character_escape
- || tokenizer.parse_state.constructs.hard_break_escape
- {
- markers.push(Code::Char('\\'));
- }
- if tokenizer.parse_state.constructs.label_end {
- markers.push(Code::Char(']'));
- }
- if tokenizer.parse_state.constructs.attention {
- markers.push(Code::Char('_'));
- }
- if tokenizer.parse_state.constructs.code_text {
- markers.push(Code::Char('`'));
- }
-
- before_marker(tokenizer, code, markers)
-}
+const MARKERS: [Code; 12] = [
+ Code::VirtualSpace, // `whitespace`
+ Code::Char('\t'), // `whitespace`
+ Code::Char(' '), // `hard_break_trailing`, `whitespace`
+ Code::Char('!'), // `label_start_image`
+ Code::Char('&'), // `character_reference`
+ Code::Char('*'), // `attention`
+ Code::Char('<'), // `autolink`, `html_text`
+ Code::Char('['), // `label_start_link`
+ Code::Char('\\'), // `character_escape`, `hard_break_escape`
+ Code::Char(']'), // `label_end`
+ Code::Char('_'), // `attention`
+ Code::Char('`'), // `code_text`
+];
/// Before text.
-fn before_marker(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> StateFnResult {
+pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
match code {
Code::None => (State::Ok, None),
_ => tokenizer.attempt_n(
@@ -90,8 +64,8 @@ fn before_marker(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> S
Box::new(whitespace),
],
|ok| {
- let func = if ok { before_marker } else { before_data };
- Box::new(move |t, c| func(t, c, markers))
+ let func = if ok { start } else { before_data };
+ Box::new(func)
},
)(tokenizer, code),
}
@@ -102,7 +76,6 @@ fn before_marker(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> S
/// ```markdown
/// |qwe
/// ```
-fn before_data(tokenizer: &mut Tokenizer, code: Code, markers: Vec<Code>) -> StateFnResult {
- let copy = markers.clone();
- tokenizer.go(|t, c| data(t, c, copy), |t, c| before_marker(t, c, markers))(tokenizer, code)
+fn before_data(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
+ tokenizer.go(|t, c| data(t, c, &MARKERS), start)(tokenizer, code)
}