Mountain/Environment/
SourceControlManagementProvider.rs

1// File: Mountain/Source/Environment/SourceControlManagementProvider.rs
2
3//! # SourceControlManagementProvider Implementation
4//!
5//! Implements the `SourceControlManagementProvider` trait for the
6//! `MountainEnvironment`.
7
8#![allow(non_snake_case, non_camel_case_types)]
9
10use Common::{
11	Error::CommonError::CommonError,
12	SourceControlManagement::{
13		DTO::{
14			SourceControlCreateDTO::SourceControlCreateDTO,
15			SourceControlGroupUpdateDTO::SourceControlGroupUpdateDTO,
16			SourceControlInputBoxDTO::SourceControlInputBoxDTO,
17			SourceControlManagementGroupDTO::SourceControlManagementGroupDTO,
18			SourceControlManagementProviderDTO::SourceControlManagementProviderDTO,
19			SourceControlUpdateDTO::SourceControlUpdateDTO,
20		},
21		SourceControlManagementProvider::SourceControlManagementProvider,
22	},
23};
24use async_trait::async_trait;
25use log::{info, warn};
26use serde_json::{Value, json};
27use tauri::Emitter;
28
29use super::{MountainEnvironment::MountainEnvironment, Utility};
30
31#[async_trait]
32impl SourceControlManagementProvider for MountainEnvironment {
33	async fn CreateSourceControl(&self, ProviderDataValue:Value) -> Result<u32, CommonError> {
34		let ProviderData:SourceControlCreateDTO = serde_json::from_value(ProviderDataValue)?;
35
36		let Handle = self.ApplicationState.GetNextSourceControlManagementProviderHandle();
37
38		info!(
39			"[SourceControlManagementProvider] Creating new SCM provider with handle {}",
40			Handle
41		);
42
43		let ProviderState = SourceControlManagementProviderDTO {
44			Handle,
45			Label:ProviderData.Label,
46			RootURI:Some(json!({ "external": ProviderData.RootUri.to_string() })),
47			CommitTemplate:None,
48			Count:None,
49			InputBox:None,
50		};
51
52		self.ApplicationState
53			.SourceControlManagementProviders
54			.lock()
55			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?
56			.insert(Handle, ProviderState.clone());
57
58		self.ApplicationState
59			.SourceControlManagementGroups
60			.lock()
61			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?
62			.insert(Handle, Default::default());
63
64		self.ApplicationHandle
65			.emit("sky://scm/provider/added", ProviderState)
66			.map_err(|Error| {
67				CommonError::UserInterfaceInteraction { Reason:format!("Failed to emit scm event: {}", Error) }
68			})?;
69
70		Ok(Handle)
71	}
72
73	async fn DisposeSourceControl(&self, ProviderHandle:u32) -> Result<(), CommonError> {
74		info!(
75			"[SourceControlManagementProvider] Disposing SCM provider with handle {}",
76			ProviderHandle
77		);
78
79		self.ApplicationState
80			.SourceControlManagementProviders
81			.lock()
82			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?
83			.remove(&ProviderHandle);
84
85		self.ApplicationState
86			.SourceControlManagementGroups
87			.lock()
88			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?
89			.remove(&ProviderHandle);
90
91		self.ApplicationHandle
92			.emit("sky://scm/provider/removed", ProviderHandle)
93			.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
94
95		Ok(())
96	}
97
98	async fn UpdateSourceControl(&self, ProviderHandle:u32, UpdateDataValue:Value) -> Result<(), CommonError> {
99		let UpdateData:SourceControlUpdateDTO = serde_json::from_value(UpdateDataValue)?;
100
101		info!("[SourceControlManagementProvider] Updating provider {}", ProviderHandle);
102
103		let mut ProvidersGuard = self
104			.ApplicationState
105			.SourceControlManagementProviders
106			.lock()
107			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
108
109		if let Some(Provider) = ProvidersGuard.get_mut(&ProviderHandle) {
110			if let Some(count) = UpdateData.Count {
111				Provider.Count = Some(count);
112			}
113
114			if let Some(value) = UpdateData.InputBoxValue {
115				if let Some(input_box) = &mut Provider.InputBox {
116					input_box.Value = value;
117				}
118			}
119
120			let ProviderClone = Provider.clone();
121
122			// Release lock before emitting
123			drop(ProvidersGuard);
124
125			self.ApplicationHandle
126				.emit(
127					"sky://scm/provider/changed",
128					json!({ "handle": ProviderHandle, "provider": ProviderClone }),
129				)
130				.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
131		}
132
133		Ok(())
134	}
135
136	async fn UpdateSourceControlGroup(&self, ProviderHandle:u32, GroupDataValue:Value) -> Result<(), CommonError> {
137		let GroupData:SourceControlGroupUpdateDTO = serde_json::from_value(GroupDataValue)?;
138
139		info!(
140			"[SourceControlManagementProvider] Updating group '{}' for provider {}",
141			GroupData.GroupID, ProviderHandle
142		);
143
144		let mut GroupsGuard = self
145			.ApplicationState
146			.SourceControlManagementGroups
147			.lock()
148			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
149
150		if let Some(ProviderGroups) = GroupsGuard.get_mut(&ProviderHandle) {
151			let Group = ProviderGroups.entry(GroupData.GroupID.clone()).or_insert_with(|| {
152				SourceControlManagementGroupDTO {
153					ProviderHandle,
154					Identifier:GroupData.GroupID.clone(),
155					Label:GroupData.Label.clone(),
156				}
157			});
158
159			Group.Label = GroupData.Label;
160
161			let GroupClone = Group.clone();
162
163			// Release lock before emitting
164			drop(GroupsGuard);
165
166			self.ApplicationHandle
167				.emit(
168					"sky://scm/group/changed",
169					json!({ "providerHandle": ProviderHandle, "group": GroupClone }),
170				)
171				.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
172		} else {
173			warn!(
174				"[SourceControlManagementProvider] Received group update for unknown provider handle: {}",
175				ProviderHandle
176			);
177		}
178
179		Ok(())
180	}
181
182	async fn RegisterInputBox(&self, ProviderHandle:u32, InputBoxDataValue:Value) -> Result<(), CommonError> {
183		let InputBoxData:SourceControlInputBoxDTO = serde_json::from_value(InputBoxDataValue)?;
184
185		info!(
186			"[SourceControlManagementProvider] Registering input box for provider {}",
187			ProviderHandle
188		);
189
190		let mut ProvidersGuard = self
191			.ApplicationState
192			.SourceControlManagementProviders
193			.lock()
194			.map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
195
196		if let Some(Provider) = ProvidersGuard.get_mut(&ProviderHandle) {
197			Provider.InputBox = Some(InputBoxData);
198
199			let ProviderClone = Provider.clone();
200
201			// Release lock before emitting
202			drop(ProvidersGuard);
203
204			self.ApplicationHandle
205				.emit(
206					"sky://scm/provider/changed",
207					json!({ "handle": ProviderHandle, "provider": ProviderClone }),
208				)
209				.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
210		}
211
212		Ok(())
213	}
214}