1use std::fmt::Display;
2use std::str::FromStr;
3
4use super::Property;
5use crate::ParseError;
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct Update {
9 pub id: u64,
10 pub props: Vec<Property>,
11}
12
13impl FromStr for Update {
14 type Err = ParseError;
15
16 fn from_str(line: &str) -> Result<Self, Self::Err> {
17 let (id, mut rest) = line.split_once(',').ok_or(ParseError::Eol)?;
18 let id = u64::from_str_radix(id, 16)?;
19 let mut props = Vec::new();
20
21 let mut prev = None;
22 let mut offset = 0;
23 for (i, ch) in rest.char_indices() {
24 if ch == ',' && prev != Some('\\') {
25 let (kv, r) = rest.split_at(i - offset);
26 rest = r.strip_prefix(',').unwrap_or(rest);
27 offset = i + 1;
28
29 props.push(Property::from_str(kv)?);
30 }
31
32 prev = Some(ch);
33 }
34
35 if !rest.is_empty() {
36 props.push(Property::from_str(rest)?);
37 }
38
39 Ok(Update { id, props })
40 }
41}
42
43impl Display for Update {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 write!(f, "{}", self.id)?;
46 for p in &self.props {
47 write!(f, ",{p}")?;
48 }
49 Ok(())
50 }
51}