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
19		Self { DirtyUris:Arc::new(StandardMutex::new(HashSet::new())) }
20	}
21}
22
23impl WorkingCopyState {
24	/// Returns `true` if the given URI has unsaved changes.
25	pub fn IsDirty(&self, Uri:&str) -> bool {
26		self.DirtyUris.lock().ok().map(|Guard| Guard.contains(Uri)).unwrap_or(false)
27	}
28
29	/// Mark a URI as dirty or clean.
30	pub fn SetDirty(&self, Uri:&str, Dirty:bool) {
31		if let Ok(mut Guard) = self.DirtyUris.lock() {
32			if Dirty {
33				Guard.insert(Uri.to_owned());
34
35				dev_log!("workingcopy", "[WorkingCopyState] URI marked dirty: {}", Uri);
36			} else {
37				Guard.remove(Uri);
38
39				dev_log!("workingcopy", "[WorkingCopyState] URI marked clean: {}", Uri);
40			}
41		}
42	}
43
44	/// Return all URIs with unsaved changes.
45	pub fn GetAllDirty(&self) -> Vec<String> {
46		self.DirtyUris
47			.lock()
48			.ok()
49			.map(|Guard| Guard.iter().cloned().collect())
50			.unwrap_or_default()
51	}
52
53	/// Return the count of resources with unsaved changes.
54	pub fn GetDirtyCount(&self) -> usize { self.DirtyUris.lock().ok().map(|Guard| Guard.len()).unwrap_or(0) }
55}