battler/config/
clause.rs

1use std::str::FromStr;
2
3use anyhow::Result;
4use battler_data::{
5    ClauseData,
6    ClauseValueType,
7    Id,
8    Identifiable,
9    Type,
10};
11
12use crate::{
13    effect::fxlang,
14    error::general_error,
15};
16
17/// A rule that modifies the validation, start, or team preview stages of a battle.
18///
19/// A clause is a generalization of a rule: a clause can be a compound rule made up of several more
20/// rules, or it can be a simple rule with an assigned value.
21#[derive(Clone)]
22pub struct Clause {
23    id: Id,
24    pub data: ClauseData,
25    pub effect: fxlang::Effect,
26}
27
28impl Clause {
29    /// Creates a new clause.
30    pub fn new(id: Id, data: ClauseData) -> Self {
31        let effect = data.effect.clone().try_into().unwrap_or_default();
32        Self { id, data, effect }
33    }
34
35    /// Validates the given value according to clause's configuration.
36    pub fn validate_value(&self, value: &str) -> Result<()> {
37        if value.is_empty() {
38            if self.data.requires_value {
39                return Err(general_error("missing value"));
40            }
41            Ok(())
42        } else {
43            match self.data.value_type {
44                Some(ClauseValueType::Type) => {
45                    Type::from_str(value).map_err(general_error).map(|_| ())
46                }
47                Some(ClauseValueType::PositiveInteger) => {
48                    value.parse::<u32>().map_err(general_error).and_then(|val| {
49                        if val > 0 {
50                            Ok(())
51                        } else {
52                            Err(general_error("integer cannot be 0"))
53                        }
54                    })
55                }
56                Some(ClauseValueType::NonNegativeInteger) => {
57                    value.parse::<u32>().map_err(general_error).map(|_| ())
58                }
59                _ => Ok(()),
60            }
61        }
62    }
63}
64
65impl Identifiable for Clause {
66    fn id(&self) -> &Id {
67        &self.id
68    }
69}