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, IPC::SkyEvent::SkyEvent};
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
17	name:String,
18
19	language_identifier:Option<String>,
20) -> Result<String, CommonError> {
21	dev_log!("output", "[OutputProvider] Registering channel: '{}'", name);
22
23	// Validate channel name
24	if name.is_empty() {
25		return Err(CommonError::InvalidArgument {
26			ArgumentName:"Name".into(),
27			Reason:"Channel name cannot be empty".into(),
28		});
29	}
30
31	if name.len() > 256 {
32		return Err(CommonError::InvalidArgument {
33			ArgumentName:"Name".into(),
34			Reason:"Channel name exceeds maximum length of 256 characters".into(),
35		});
36	}
37
38	// Validate language identifier length if provided
39	if let Some(ref lang_id) = language_identifier {
40		if lang_id.len() > 64 {
41			return Err(CommonError::InvalidArgument {
42				ArgumentName:"LanguageIdentifier".into(),
43				Reason:"Language identifier exceeds maximum length of 64 characters".into(),
44			});
45		}
46	}
47
48	let channel_identifier = name.clone();
49
50	let mut channels_guard = env
51		.ApplicationState
52		.Feature
53		.OutputChannels
54		.OutputChannels
55		.lock()
56		.map_err(Utility::ErrorMapping::MapApplicationStateLockErrorToCommonError)?;
57
58	channels_guard.entry(channel_identifier.clone()).or_insert_with(|| {
59		OutputChannelStateDTO::Create(&name, language_identifier.clone()).unwrap_or_else(|e| {
60			dev_log!("output", "error: [OutputProvider] Failed to create output channel: {}", e);
61			OutputChannelStateDTO::default()
62		})
63	});
64
65	drop(channels_guard);
66
67	let event_payload = json!({ "id": channel_identifier, "name": name, "languageId": language_identifier });
68
69	env.ApplicationHandle
70		.emit(SkyEvent::OutputCreate.AsStr(), event_payload)
71		.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })?;
72
73	Ok(channel_identifier)
74}
75
76/// Disposes of an output channel permanently.
77pub(super) async fn dispose_channel(
78	env:&crate::Environment::MountainEnvironment::MountainEnvironment,
79
80	channel_identifier:String,
81) -> Result<(), CommonError> {
82	dev_log!("output", "[OutputProvider] Disposing channel: '{}'", channel_identifier);
83
84	env.ApplicationState
85		.Feature
86		.OutputChannels
87		.OutputChannels
88		.lock()
89		.map_err(Utility::ErrorMapping::MapApplicationStateLockErrorToCommonError)?
90		.remove(&channel_identifier);
91
92	env.ApplicationHandle
93		.emit(SkyEvent::OutputDispose.AsStr(), json!({ "channel": channel_identifier }))
94		.map_err(|Error| CommonError::UserInterfaceInteraction { Reason:Error.to_string() })
95}