diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-07-20 17:19:17 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-07-20 17:19:17 +0200 |
commit | a820d849c3e20a1d72137072d70a7c8e00306f98 (patch) | |
tree | c2916ab31d6d481e0b53a06aa9b95dfcddd4163f /src/util/encode.rs | |
parent | 7894ec75a7070591c3499fce1f409563c4edc7d7 (diff) | |
download | markdown-rs-a820d849c3e20a1d72137072d70a7c8e00306f98.tar.gz markdown-rs-a820d849c3e20a1d72137072d70a7c8e00306f98.tar.bz2 markdown-rs-a820d849c3e20a1d72137072d70a7c8e00306f98.zip |
Refactor to improve allocation around strings
Diffstat (limited to 'src/util/encode.rs')
-rw-r--r-- | src/util/encode.rs | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/src/util/encode.rs b/src/util/encode.rs index a3bd589..965ea5c 100644 --- a/src/util/encode.rs +++ b/src/util/encode.rs @@ -20,37 +20,31 @@ /// ## References /// /// * [`micromark-util-encode` in `micromark`](https://github.com/micromark/micromark/tree/main/packages/micromark-util-encode) -pub fn encode(value: &str) -> String { - let mut result: Vec<&str> = vec![]; - let mut start = 0; - let mut index = 0; +pub fn encode<S: Into<String>>(value: S) -> String { + let mut value = value.into(); - for byte in value.bytes() { - if let Some(replacement) = match byte { - b'&' => Some("&"), - b'"' => Some("""), - b'<' => Some("<"), - b'>' => Some(">"), - _ => None, - } { - if start != index { - result.push(&value[start..index]); - } + // It’ll grow a bit bigger for each dangerous character. + let mut result = String::with_capacity(value.len()); - result.push(replacement); - start = index + 1; - } - - index += 1; + while let Some(indice) = value.find(check) { + let after = value.split_off(indice + 1); + let dangerous = value.pop().unwrap(); + result.push_str(&value); + result.push_str(match dangerous { + '&' => "&", + '"' => """, + '<' => "<", + '>' => ">", + _ => unreachable!("xxx"), + }); + value = after; } - if start == 0 { - value.to_string() - } else { - if start < index { - result.push(&value[start..index]); - } + result.push_str(&value); - result.join("") - } + result +} + +fn check(char: char) -> bool { + matches!(char, '&' | '"' | '<' | '>') } |