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