rl_model/model/
invariant.rs

1use super::*;
2use crate::parser::{Position, RlError};
3use std::collections::HashMap;
4
5#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
6pub struct InvariantId(pub SkillId, pub usize);
7impl Id for InvariantId {
8    fn index(&self) -> usize {
9        self.1
10    }
11}
12impl InvariantId {
13    pub fn skill(&self) -> SkillId {
14        self.0
15    }
16}
17
18#[derive(Debug, Clone)]
19pub struct Invariant {
20    id: InvariantId,
21    name: String,
22    guard: Expr,
23    effects: Vec<Effect>,
24    position: Option<Position>,
25}
26
27impl Invariant {
28    pub fn new<S: Into<String>>(
29        name: S,
30        guard: Expr,
31        effects: Vec<Effect>,
32        position: Option<Position>,
33    ) -> Self {
34        let id = InvariantId::default();
35        let name = name.into();
36        Self {
37            id,
38            name,
39            guard,
40            effects,
41            position,
42        }
43    }
44
45    pub fn guard(&self) -> &Expr {
46        &self.guard
47    }
48
49    pub fn effects(&self) -> &Vec<Effect> {
50        &self.effects
51    }
52
53    //---------- Resolve ----------
54
55    pub fn resolve_resource(&mut self, map: &HashMap<String, ResourceId>) -> Result<(), RlError> {
56        self.guard.resolve_resource(map)?;
57        for x in self.effects.iter_mut() {
58            x.resolve_resource(map)?;
59        }
60        Ok(())
61    }
62
63    pub fn resolve_state(&mut self, map: &HashMap<String, StateId>) -> Result<(), RlError> {
64        self.guard.resolve_state(map)?;
65        for x in self.effects.iter_mut() {
66            x.resolve_state(map)?;
67        }
68        Ok(())
69    }
70}
71
72impl Named<InvariantId> for Invariant {
73    fn id(&self) -> InvariantId {
74        self.id
75    }
76
77    fn set_id(&mut self, id: InvariantId) {
78        self.id = id;
79    }
80
81    fn name(&self) -> &str {
82        &self.name
83    }
84
85    fn position(&self) -> Option<Position> {
86        self.position.clone()
87    }
88}
89
90impl ToLang for Invariant {
91    fn to_lang(&self, skillset: &Skillset) -> String {
92        let mut s = format!("{} {{\n", self.name);
93        // guard
94        s.push_str(&format!(
95            "\t\t\t\t\tguard {}\n",
96            self.guard.to_lang(skillset)
97        ));
98        // Effects
99        if !self.effects.is_empty() {
100            s.push_str("\t\t\t\t\teffect {\n");
101            for x in self.effects.iter() {
102                s.push_str(&format!("\t\t\t\t\t\t{}\n", x.to_lang(skillset)))
103            }
104            s.push_str("\t\t\t\t\t}\n");
105        }
106        //
107        s.push_str("\t\t\t\t}\n");
108        s
109    }
110}
111
112impl std::fmt::Display for Invariant {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        write!(f, "{}", self.name)
115    }
116}