Skip to main content

Mountain/Environment/OutputProvider/
ChannelLifecycle.rs

1//! # Output Channel Lifecycle Helpers
2//!
3//! Internal helper functions for output channel creation and disposal.
4//! These are not public API - they are called by the main provider
5//! implementation.
6
7use CommonLibrary::Error::CommonError::CommonError;
8use serde_json::json;
9use tauri::Emitter;
10
11use crate::{ApplicationState::DTO::OutputChannelStateDTO::OutputChannelStateDTO, Environment::Utility, dev_log};
12
13/// Registers a new output channel.
14pub(super) async fn register_channel(
15	env:&crate::Environment::MountainEnvironment::MountainEnvironment,
16	name:String,
17	language_identifier:Option<String>,
18) -> Result<String, CommonError> {
19	dev_log!("output", "[OutputProvider] Registering channel: '{}'", name);
20
21	// Validate channel name
22	if name.is_empty() {
23		return Err(CommonError::InvalidArgument {
24			ArgumentName:"Name".into(),
25			Reason:"Channel name cannot be empty".into(),
26		});
27	}
28
29	if name.len() > 256 {
30		return Err(CommonError::InvalidArgument {
31			ArgumentName:"Name".into(),
32			Reason:"Channel name exceeds maximum length of 256 characters".into(),
33		});
34	}
35
36	// Validate language identifier length if provided
37	if let Some(ref lang_id) = language_identifier {
38		if lang_id.len() > 64 {
39			return Err(CommonError::InvalidArgument {
40				ArgumentName:"LanguageIdentifier".into(),
41				Reason:"Language identifier exceeds maximum length of 64 characters".into(),
42			});
43		}
44	}
45
46	let channel_identifier = name.clone();
47
48	let mut channels_guard = env
49		.ApplicationState
50		.Feature
51		.OutputChannels
52		.OutputChannels
53		.lock()
54		.map_err(Utility::MapApplicationStateLockErrorToCommonError)?;
55
56	channels_guard.entry(channel_identifier.clone()).or_insert_with(|| {
57		OutputChannelStateDTO::Create(&name, language_identifier.clone()).unwrap_or_else(|e| {
58			dev_log!("output", "error: [OutputProvider] Failed to create output channel: {}", e);
59			OutputChannelStateDTO::default()
60		})
61	});
62
63	drop(channels_guard);
64
65	let event_payload = json!({ "Id": channel_identifier, "Name": name, "LanguageId": language_identifier });
66
67	env.ApplicationHandle
68		.emit("sky://output/create", event_payload)
69		.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
70
71	Ok(channel_identifier)
72}
73
74/// Disposes of an output channel permanently.
75pub(super) async fn dispose_channel(
76	env:&crate::Environment::MountainEnvironment::MountainEnvironment,
77	channel_identifier:String,
78) -> Result<(), CommonError> {
79	dev_log!("output", "[OutputProvider] Disposing channel: '{}'", channel_identifier);
80
81	env.ApplicationState
82		.Feature
83		.OutputChannels
84		.OutputChannels
85		.lock()
86		.map_err(Utility::MapApplicationStateLockErrorToCommonError)?
87		.remove(&channel_identifier);
88
89	env.ApplicationHandle
90		.emit("sky://output/dispose", json!({ "Id": channel_identifier }))
91		.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })
92}