Skip to main content

rflog_parser/
info_line.rs

1use anyhow::{bail, Context, Result};
2use regex::Regex;
3
4const LOG_MARK: &str = "Riverfall Launcher Log Format";
5
6macro_rules! get_element {
7    ($i:ident,$n:tt,$ii:tt,$t:ty) => {
8      $i.get($ii)
9        .context(anyhow::anyhow!("Unable to get element {} (№{}) of RFLogMark", $n, $ii))?
10        .as_str()
11        .parse::<$t>().ok().context(anyhow::anyhow!("Unable to cast element {} (№{}, &str) to type {}", $n, $ii, stringify!($t))) // idk will it gonna work or not
12    };
13}
14
15#[derive(Debug, Clone)]
16pub struct Version {
17  pub major: u16,
18  pub minor: u16,
19  pub patch: u16
20}
21
22impl ToString for Version {
23  fn to_string(&self) -> String {
24    format!("{}.{}.{}", self.major, self.minor, self.patch)
25  }
26}
27
28#[derive(Debug, Clone)]
29pub struct RFLogInfoLine {
30  pub launcher_version: Version,
31  pub player_nick: String,
32  pub game_client: String,
33  pub os: String,
34  pub os_version: String
35}
36
37pub(crate) fn parse(line: &str) -> Result<RFLogInfoLine> {
38  let re = Regex::new(r"([^:]+):\[(\d+)\.(\d+)\.(\d+);([^;]+);([^;]+);([^;]+);([^\]]+)\]").unwrap();
39
40  if let Some(caps) = re.captures(line) {
41    let log_mark = caps.get(1).context("Invalid format: Unable to get RFLogMark")?.as_str();
42
43    if log_mark != LOG_MARK {
44      bail!("Invalid format: Unable to get RFLogMark");
45    }
46
47    let major = get_element!(caps, "Version (major)", 2, u16)?;
48    let minor = get_element!(caps, "Version (minor)", 3, u16)?;
49    let patch = get_element!(caps, "Version (patch)", 4, u16)?;
50    let player_nick = get_element!(caps, "Username", 5, String)?;
51    let os = get_element!(caps, "OS", 6, String)?;
52    let os_version = get_element!(caps, "OS Version", 7, String)?;
53    let game_client = get_element!(caps, "Game Client", 8, String)?;
54
55    Ok(
56      RFLogInfoLine {
57        launcher_version: Version { major, minor, patch },
58        player_nick,
59        game_client,
60        os,
61        os_version
62      }
63    )
64  } else {
65    bail!("Invalid format: Unable to get RFLogMark")
66  }
67}