wotw_seedgen/languages/logic/
states.rs

1use serde::Deserialize;
2
3use crate::uber_state::{
4    UberIdentifier, UberStateComparator, UberStateCondition, UberStateTrigger,
5};
6
7/// Information about an obtainable world state
8#[derive(Debug, Clone, PartialEq)]
9pub struct NamedState {
10    pub name: String,
11    pub trigger: UberStateTrigger,
12}
13#[derive(Deserialize)]
14#[serde(rename_all = "PascalCase")]
15struct StateEntry {
16    node_identifier: String,
17    uber_group: u16,
18    uber_id: u16,
19    uber_state_value: Option<u32>,
20}
21
22/// Parses state data from a csv format
23///
24/// # Examples
25///
26/// ```
27/// # use wotw_seedgen::logic::{parse_states, NamedState};
28/// use wotw_seedgen::uber_state::UberStateTrigger;
29///
30/// let input = "
31/// NodeIdentifier, UberGroup, UberId, UberStateValue
32/// MarshSpawn.HowlBurnt, 21786, 25095, 1
33/// ";
34/// let states = parse_states(input).unwrap();
35///
36/// assert_eq!(states, vec![
37///     NamedState {
38///         name: "MarshSpawn.HowlBurnt".to_string(),
39///         trigger: "21786|25095>=1".parse().unwrap(),
40///     }
41/// ]);
42/// ```
43pub fn parse_states(input: &str) -> Result<Vec<NamedState>, String> {
44    let mut reader = csv::ReaderBuilder::new()
45        .trim(csv::Trim::All)
46        .from_reader(input.as_bytes());
47
48    let states = reader
49        .deserialize()
50        .map(|record| {
51            let StateEntry {
52                node_identifier,
53                uber_group,
54                uber_id,
55                uber_state_value,
56            } = record.map_err(|err| err.to_string())?;
57
58            let identifier = UberIdentifier::new(uber_group, uber_id);
59            let condition = uber_state_value.map(|value| UberStateCondition {
60                comparator: UberStateComparator::GreaterOrEquals,
61                value,
62            });
63            let trigger = UberStateTrigger {
64                identifier,
65                condition,
66            };
67            Ok(NamedState {
68                name: node_identifier,
69                trigger,
70            })
71        })
72        .collect::<Result<_, String>>()?;
73
74    Ok(states)
75}