konnektoren_core/persistence/
memory_persistence.rs

1use super::GameStatePersistence;
2use crate::game::GameState;
3use crate::persistence::error::{PersistenceError, Result};
4use std::cell::RefCell;
5use std::rc::Rc;
6
7#[derive(Debug, Default)]
8pub struct MemoryPersistence {
9    game_state: Rc<RefCell<GameState>>,
10}
11
12unsafe impl Send for MemoryPersistence {}
13unsafe impl Sync for MemoryPersistence {}
14
15impl MemoryPersistence {
16    pub fn new(game_state: GameState) -> Self {
17        MemoryPersistence {
18            game_state: Rc::new(RefCell::new(game_state)),
19        }
20    }
21}
22
23impl GameStatePersistence for MemoryPersistence {
24    fn save_game_state(&self, state: &GameState) -> Result<()> {
25        match self.game_state.try_borrow_mut() {
26            Ok(mut gs) => {
27                *gs = state.clone();
28                Ok(())
29            }
30            Err(_) => Err(PersistenceError::AccessError(
31                "Failed to get mutable borrow of game state".to_string(),
32            )),
33        }
34    }
35
36    fn load_game_state(&self) -> Result<GameState> {
37        self.game_state
38            .try_borrow()
39            .map(|gs| gs.clone())
40            .map_err(|_| PersistenceError::AccessError("Failed to borrow game state".to_string()))
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use crate::game::GameState;
48
49    #[test]
50    fn test_save_game_state() {
51        let persistence = MemoryPersistence::default();
52        let state = GameState::default();
53
54        let result = persistence.save_game_state(&state);
55        assert!(result.is_ok());
56    }
57
58    #[test]
59    fn test_load_game_state() {
60        let persistence = MemoryPersistence::default();
61        let state = GameState::default();
62
63        let _ = persistence.save_game_state(&state);
64
65        let loaded_state = persistence.load_game_state().unwrap();
66        assert_eq!(state, loaded_state);
67    }
68
69    #[test]
70    fn test_concurrent_access_errors() {
71        let persistence = MemoryPersistence::default();
72        let state = GameState::default();
73
74        // Create a borrow that will cause subsequent borrows to fail
75        let _borrow = persistence.game_state.borrow_mut();
76
77        // This should fail with an AccessError
78        let save_result = persistence.save_game_state(&state);
79        assert!(save_result.is_err());
80
81        if let Err(err) = save_result {
82            match err {
83                PersistenceError::AccessError(_) => {} // Expected error type
84                _ => panic!("Unexpected error type: {:?}", err),
85            }
86        }
87
88        // This should also fail with an AccessError
89        let load_result = persistence.load_game_state();
90        assert!(load_result.is_err());
91
92        if let Err(err) = load_result {
93            match err {
94                PersistenceError::AccessError(_) => {} // Expected error type
95                _ => panic!("Unexpected error type: {:?}", err),
96            }
97        }
98    }
99}