pocket_relay_utils/
parse.rs

1//! Utilites for parsing ME3 strings
2
3use std::str::{FromStr, Split};
4
5/// Structure for parsing ME3 format strings which are strings made up of sets
6/// of data split by ; that each start with the 20;4;
7///
8/// # Example
9/// ```20;4;Sentinel;20;0.0000;50```
10pub struct MEStringParser<'a> {
11    split: Split<'a, char>,
12}
13
14impl<'a> MEStringParser<'a> {
15    pub fn new(value: &'a str) -> Option<MEStringParser<'a>> {
16        if !value.starts_with("20;4;") {
17            return None;
18        }
19        let split = value[5..].split(';');
20        Some(MEStringParser { split })
21    }
22
23    pub fn skip(&mut self, count: usize) -> Option<()> {
24        for _ in 0..count {
25            self.split.next()?;
26        }
27        Some(())
28    }
29
30    pub fn next_str(&mut self) -> Option<String> {
31        let next = self.split.next()?;
32        Some(next.to_string())
33    }
34
35    pub fn parse_next<F: FromStr>(&mut self) -> Option<F> {
36        let next = self.split.next()?;
37        next.parse::<F>().ok()
38    }
39
40    pub fn next_bool(&mut self) -> Option<bool> {
41        let next = self.split.next()?;
42        if next == "True" {
43            Some(true)
44        } else if next == "False" {
45            Some(false)
46        } else {
47            None
48        }
49    }
50}
51
52#[cfg(test)]
53mod test {
54    use crate::parse::MEStringParser;
55
56    #[test]
57    fn test_a() {
58        let value = "20;4;AABB;123;DWADA";
59        let mut parser = MEStringParser::new(value).unwrap();
60        assert_eq!(parser.next_str().unwrap(), "AABB");
61        assert_eq!(parser.parse_next::<u16>().unwrap(), 123);
62        assert_eq!(parser.next_str().unwrap(), "DWADA");
63    }
64}