Skip to main content

Mountain/ApplicationState/Internal/Persistence/
MementoSaver.rs

1//! # MementoSaver Module (Internal)
2//!
3//! ## RESPONSIBILITIES
4//! Saves memento state to disk for crash recovery and state persistence.
5//! Asynchronously saves memento to JSON file with proper error handling.
6//!
7//! ## ARCHITECTURAL ROLE
8//! MementoSaver is part of the **Internal::Persistence** module, handling
9//! memento saving operations.
10//!
11//! ## KEY COMPONENTS
12//! - SaveMementoToDisk: Main function for saving memento
13//!
14//! ## ERROR HANDLING
15//! - Returns Result with CommonError on failure
16//! - Creates directory structure if needed
17//! - Proper error logging
18//!
19//! ## LOGGING
20//! All operations are logged at appropriate levels (debug, info, warn, error).
21//!
22//! ## PERFORMANCE CONSIDERATIONS
23//! - Asynchronous file I/O
24//! - Proper error handling and recovery
25//!
26//! ## TODO
27//! - [ ] Add checksum calculation
28//! - [ ] Implement atomic writes
29//! - [ ] Add compression support
30
31use std::{collections::HashMap, fs, path::Path};
32
33use serde_json::Value;
34use CommonLibrary::Error::CommonError::CommonError;
35
36use crate::dev_log;
37
38/// Asynchronously saves Memento storage data to a JSON file.
39///
40/// # Arguments
41/// * `StorageFilePath` - Path to the memento storage file
42/// * `MementoData` - The memento data to save
43///
44/// # Returns
45/// Result indicating success or CommonError on failure
46///
47/// # Errors
48/// Returns CommonError for file I/O or serialization errors
49///
50/// # Behavior
51/// - Creates parent directory if it doesn't exist
52/// - Serializes data to JSON
53/// - Writes to file atomically (creates temp file then renames)
54pub async fn Fn(StorageFilePath:&Path, MementoData:&HashMap<String, Value>) -> Result<(), CommonError> {
55	// Ensure parent directory exists
56	if let Some(parent) = StorageFilePath.parent() {
57		if !parent.exists() {
58			fs::create_dir_all(parent).map_err(|e| {
59				dev_log!(
60					"storage",
61					"error: [MementoSaver] Failed to create directory '{}': {}",
62					parent.display(),
63					e
64				);
65
66				CommonError::FileSystemIO {
67					Path:parent.to_path_buf(),
68					Description:format!("Failed to create directory: {}", e),
69				}
70			})?;
71
72			dev_log!("storage", "[MementoSaver] Created directory: {}", parent.display());
73		}
74	}
75
76	// Serialize memento data to JSON
77	let json_content = serde_json::to_string_pretty(MementoData).map_err(|e| {
78		dev_log!("storage", "error: [MementoSaver] Failed to serialize memento data: {}", e);
79
80		CommonError::SerializationError { Description:format!("Failed to serialize memento data: {}", e) }
81	})?;
82
83	// Write to temporary file first, then rename for atomic write
84	let temp_path = StorageFilePath.with_extension("json.tmp");
85
86	fs::write(&temp_path, json_content).map_err(|e| {
87		dev_log!(
88			"storage",
89			"error: [MementoSaver] Failed to write memento to temp file '{}': {}",
90			temp_path.display(),
91			e
92		);
93
94		CommonError::FileSystemIO { Path:temp_path.clone(), Description:format!("Failed to write memento: {}", e) }
95	})?;
96
97	// Atomic rename from temp to actual file
98	fs::rename(&temp_path, StorageFilePath).map_err(|e| {
99		dev_log!(
100			"storage",
101			"error: [MementoSaver] Failed to rename temp file to '{}': {}",
102			StorageFilePath.display(),
103			e
104		);
105
106		// Clean up temp file if rename fails
107		let _ = fs::remove_file(&temp_path);
108
109		CommonError::FileSystemIO {
110			Path:StorageFilePath.to_path_buf(),
111			Description:format!("Failed to rename memento file: {}", e),
112		}
113	})?;
114
115	dev_log!(
116		"storage",
117		"[MementoSaver] Successfully saved memento to: {}",
118		StorageFilePath.display()
119	);
120
121	Ok(())
122}