Skip to main content

Mountain/ApplicationState/State/FeatureState/WorkingCopy/
WorkingCopyState.rs

1use std::{
2	collections::HashSet,
3	sync::{Arc, Mutex as StandardMutex},
4};
5
6use crate::dev_log;
7
8/// Tracks which URIs have unsaved changes (dirty state).
9/// Drives the dirty dot in editor tabs and the explorer badge count.
10#[derive(Clone)]
11pub struct WorkingCopyState {
12	DirtyUris:Arc<StandardMutex<HashSet<String>>>,
13}
14
15impl Default for WorkingCopyState {
16	fn default() -> Self {
17		dev_log!("workingcopy", "[WorkingCopyState] Initializing default working-copy state...");
18		Self { DirtyUris:Arc::new(StandardMutex::new(HashSet::new())) }
19	}
20}
21
22impl WorkingCopyState {
23	/// Returns `true` if the given URI has unsaved changes.
24	pub fn IsDirty(&self, Uri:&str) -> bool {
25		self.DirtyUris.lock().ok().map(|Guard| Guard.contains(Uri)).unwrap_or(false)
26	}
27
28	/// Mark a URI as dirty or clean.
29	pub fn SetDirty(&self, Uri:&str, Dirty:bool) {
30		if let Ok(mut Guard) = self.DirtyUris.lock() {
31			if Dirty {
32				Guard.insert(Uri.to_owned());
33				dev_log!("workingcopy", "[WorkingCopyState] URI marked dirty: {}", Uri);
34			} else {
35				Guard.remove(Uri);
36				dev_log!("workingcopy", "[WorkingCopyState] URI marked clean: {}", Uri);
37			}
38		}
39	}
40
41	/// Return all URIs with unsaved changes.
42	pub fn GetAllDirty(&self) -> Vec<String> {
43		self.DirtyUris
44			.lock()
45			.ok()
46			.map(|Guard| Guard.iter().cloned().collect())
47			.unwrap_or_default()
48	}
49
50	/// Return the count of resources with unsaved changes.
51	pub fn GetDirtyCount(&self) -> usize { self.DirtyUris.lock().ok().map(|Guard| Guard.len()).unwrap_or(0) }
52}