better tag decode

This commit is contained in:
jesopo 2023-03-22 10:07:20 +00:00
parent a3b9eca823
commit 59aacddea4
2 changed files with 18 additions and 19 deletions

View File

@ -36,10 +36,11 @@ impl<'a> TakeWord<'a> for &'a [u8] {
} }
} }
fn tag_decode(value: &mut String) { fn tag_decode(input: &str) -> String {
let mut i = 0;
let mut escaped = false; let mut escaped = false;
while let Some(char) = value.chars().nth(i) { let mut output = String::new();
for char in input.chars() {
if escaped { if escaped {
escaped = false; escaped = false;
let replace = match char { let replace = match char {
@ -50,17 +51,16 @@ fn tag_decode(value: &mut String) {
_ => char, _ => char,
}; };
value.replace_range(i - 1..i, &replace.to_string()); output.push(replace);
value.remove(i); } else if char == 0x5c as char {
// the above replace loses one character from the string, so no `i += 1`
} else {
// backslash // backslash
if char == 0x5c as char { escaped = true;
escaped = true; } else {
} output.push(char);
i += 1;
} }
} }
output
} }
pub fn tokenise(mut line: &[u8]) -> Result<Line, Error> { pub fn tokenise(mut line: &[u8]) -> Result<Line, Error> {
@ -75,12 +75,11 @@ pub fn tokenise(mut line: &[u8]) -> Result<Line, Error> {
.map_err(|_| Error::TagKeyDecode)?; .map_err(|_| Error::TagKeyDecode)?;
let tag_value = match tag_key_value { let tag_value = match tag_key_value {
b"" | b"=" => None, b"" | b"=" => None,
_ => { _ => Some(
let mut tag_value = String::from_utf8(tag_key_value.to_vec()) String::from_utf8(tag_key_value.to_vec())
.map_err(|_| Error::TagValueDecode)?; .map(|v| tag_decode(&v))
tag_decode(&mut tag_value); .map_err(|_| Error::TagValueDecode)?,
Some(tag_value) ),
}
}; };
tags_map.insert(tag_key, tag_value); tags_map.insert(tag_key, tag_value);

View File

@ -22,8 +22,8 @@ fn basic() {
#[test] #[test]
fn complex_tags() { fn complex_tags() {
let line = tokenise(b"@tag1=\\:a COMMAND").unwrap(); let line = tokenise(b"@tag1=a\\:a COMMAND").unwrap();
let tags = line.tags.unwrap(); let tags = line.tags.unwrap();
assert_eq!(tags["tag1"], Some(";a".to_string())); assert_eq!(tags["tag1"], Some("a;a".to_string()));
} }