decode message tag values

This commit is contained in:
jesopo 2023-03-21 23:09:57 +00:00
parent f262cbc463
commit a3b9eca823
2 changed files with 49 additions and 12 deletions

View File

@ -36,6 +36,33 @@ impl<'a> TakeWord<'a> for &'a [u8] {
}
}
fn tag_decode(value: &mut String) {
let mut i = 0;
let mut escaped = false;
while let Some(char) = value.chars().nth(i) {
if escaped {
escaped = false;
let replace = match char {
':' => ';',
's' => ' ',
'r' => '\r',
'n' => '\n',
_ => char,
};
value.replace_range(i - 1..i, &replace.to_string());
value.remove(i);
// the above replace loses one character from the string, so no `i += 1`
} else {
// backslash
if char == 0x5c as char {
escaped = true;
}
i += 1;
}
}
}
pub fn tokenise(mut line: &[u8]) -> Result<Line, Error> {
let tags = match line.first() {
Some(b'@') => {
@ -43,18 +70,20 @@ pub fn tokenise(mut line: &[u8]) -> Result<Line, Error> {
let mut tags_map = HashMap::new();
while !tags.is_empty() {
let mut keyvalue = tags.take_word(b';');
let tag = keyvalue.take_word(b'=');
tags_map.insert(
String::from_utf8(tag.to_vec()).map_err(|_| Error::TagKeyDecode)?,
match keyvalue {
b"" | b"=" => None,
_ => Some(
String::from_utf8(keyvalue.to_vec())
.map_err(|_| Error::TagValueDecode)?,
),
},
);
let mut tag_key_value = tags.take_word(b';');
let tag_key = String::from_utf8(tag_key_value.take_word(b'=').to_vec())
.map_err(|_| Error::TagKeyDecode)?;
let tag_value = match tag_key_value {
b"" | b"=" => None,
_ => {
let mut tag_value = String::from_utf8(tag_key_value.to_vec())
.map_err(|_| Error::TagValueDecode)?;
tag_decode(&mut tag_value);
Some(tag_value)
}
};
tags_map.insert(tag_key, tag_value);
}
Some(tags_map)

View File

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