pabitell_lib/
updates.rs

1use crate::{ItemState, World};
2use anyhow::{anyhow, Result};
3use std::fmt;
4
5pub trait Change: fmt::Debug {
6    fn change(&self, world: &mut dyn World) -> Result<()>;
7}
8
9pub struct AssignItemChange {
10    item: String,
11    state: ItemState,
12}
13
14impl AssignItemChange {
15    pub fn new(item: String, state: ItemState) -> Self {
16        Self { item, state }
17    }
18}
19
20impl fmt::Debug for AssignItemChange {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        f.debug_struct("AssignItem")
23            .field("item", &self.item)
24            .field("state", &self.state)
25            .finish()
26    }
27}
28
29impl Change for AssignItemChange {
30    fn change(&self, world: &mut dyn World) -> Result<()> {
31        let state = match &self.state {
32            ItemState::Owned(character) => {
33                world
34                    .characters()
35                    .get(character)
36                    .ok_or_else(|| anyhow!("Character {} not found", character))?;
37                ItemState::Owned(character.to_string())
38            }
39            ItemState::InScene(scene) => {
40                world
41                    .scenes()
42                    .get(scene)
43                    .ok_or_else(|| anyhow!("Scene {} not found", scene))?;
44                ItemState::InScene(scene.to_string())
45            }
46            i => i.clone(),
47        };
48
49        // Set item to character
50        let item = world
51            .items_mut()
52            .get_mut(&self.item)
53            .ok_or_else(|| anyhow!("Item '{}' is not found", self.item))?;
54
55        item.set_state(state);
56
57        Ok(())
58    }
59}
60
61pub struct MoveCharacterChange {
62    character: String,
63    scene: Option<String>,
64}
65
66impl MoveCharacterChange {
67    pub fn new(character: String, scene: Option<String>) -> Self {
68        Self { character, scene }
69    }
70}
71
72impl fmt::Debug for MoveCharacterChange {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        f.debug_struct("MoveCharacter")
75            .field("character", &self.character)
76            .field("scene", &self.scene)
77            .finish()
78    }
79}
80
81impl Change for MoveCharacterChange {
82    fn change(&self, world: &mut dyn World) -> Result<()> {
83        // Test whether scene is present in world
84        if let Some(scene) = self.scene.clone() {
85            world
86                .scenes()
87                .get(&scene)
88                .ok_or_else(|| anyhow!("Scene {} not found", scene))?;
89        }
90
91        // move character to scene
92        world
93            .characters_mut()
94            .get_mut(&self.character)
95            .ok_or_else(|| anyhow!("Character '{}' not found", &self.character))?
96            .set_scene(self.scene.clone());
97        Ok(())
98    }
99}
100
101pub struct NextSceneDialogChange {
102    scene: String,
103}
104
105impl NextSceneDialogChange {
106    pub fn new(scene: String) -> Self {
107        Self { scene }
108    }
109}
110
111impl fmt::Debug for NextSceneDialogChange {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        f.debug_struct("NextSceneDialog")
114            .field("scene", &self.scene)
115            .finish()
116    }
117}
118
119impl Change for NextSceneDialogChange {
120    fn change(&self, world: &mut dyn World) -> Result<()> {
121        world
122            .scenes_mut()
123            .get_mut(&self.scene)
124            .ok_or_else(|| anyhow!("Scene {} not found", self.scene))?
125            .next_dialog();
126        Ok(())
127    }
128}