v0.1.4-pre.007
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
// file: crates/ksp-app-config-desk/src/constants.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Application-owned tracing targets and domains.
|
||||
|
||||
/// Owning target for backend events emitted by Config Desk.
|
||||
pub(crate) const TRACING_TARGET: &str = "ksp-app-config-desk";
|
||||
/// Owning target for generic frontend events emitted through the KSP bridge.
|
||||
pub(crate) const TRACING_TARGET_FRONTEND: &str = "ksp-app-config-desk.frontend";
|
||||
/// Owning target for main-window frontend events.
|
||||
pub(crate) const TRACING_TARGET_FRONTEND_MAIN: &str = "ksp-app-config-desk.frontend.main";
|
||||
/// Owning target for splash-window frontend events.
|
||||
pub(crate) const TRACING_TARGET_FRONTEND_SPLASH: &str = "ksp-app-config-desk.frontend.splash";
|
||||
/// Structured domain used while bootstrapping Config and Logging.
|
||||
pub(crate) const TRACING_DOMAIN_BOOTSTRAP: &str = "config.bootstrap";
|
||||
/// Structured domain used by technical frontend events.
|
||||
pub(crate) const TRACING_DOMAIN_FRONTEND: &str = "frontend";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/errors.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
//! Application-local error codes for the configuration desktop shell.
|
||||
|
||||
@@ -11,3 +11,7 @@ pub(crate) const ERROR_CODE_LOGGING_BOOTSTRAP_FAILED: ksp_core_lib::ErrorCode =
|
||||
pub(crate) const ERROR_CODE_APP_STATE_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_invalid");
|
||||
/// Shared Config Desk runtime state cannot be locked safely.
|
||||
pub(crate) const ERROR_CODE_APP_STATE_LOCK_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_lock_failed");
|
||||
/// Frontend logging requested an unsupported level.
|
||||
pub(crate) const ERROR_CODE_FRONTEND_LOG_LEVEL_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_level_invalid");
|
||||
/// Frontend logging requested a target outside the application whitelist.
|
||||
pub(crate) const ERROR_CODE_FRONTEND_LOG_TARGET_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_target_invalid");
|
||||
|
||||
205
crates/ksp-app-config-desk/src/frontend_logging.rs
Normal file
205
crates/ksp-app-config-desk/src/frontend_logging.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
// file: crates/ksp-app-config-desk/src/frontend_logging.rs
|
||||
// version: 1
|
||||
|
||||
//! KSP-owned bridge for technical log events emitted by Config Desk frontend scripts.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
/// Log payload sent by Config Desk frontend scripts.
|
||||
#[derive(Clone, Debug, serde::Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/frontend_logging/FrontendLogPayloadDto.ts")]
|
||||
pub(crate) struct FrontendLogPayloadDto {
|
||||
/// Lowercase KSP log level.
|
||||
pub(crate) level: String,
|
||||
/// Whitelisted logical frontend target identifier.
|
||||
pub(crate) target_id: String,
|
||||
/// Rendered technical frontend message.
|
||||
pub(crate) message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum FrontendLogLevel {
|
||||
Trace,
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum FrontendLogTarget {
|
||||
Frontend,
|
||||
Main,
|
||||
Splash,
|
||||
}
|
||||
|
||||
/// Emits one validated frontend event through the KSP Logging facade.
|
||||
pub(crate) fn emit_frontend_log_event(payload: FrontendLogPayloadDto) -> ksp_core_lib::Result<()> {
|
||||
let level = parse_level(payload.level.as_str());
|
||||
let level = match level {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let target = parse_target(payload.target_id.as_str());
|
||||
let target = match target {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
emit_validated_frontend_log(level, target, payload.message.as_str());
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
fn parse_level(level: &str) -> ksp_core_lib::Result<FrontendLogLevel> {
|
||||
return match level.trim().to_ascii_lowercase().as_str() {
|
||||
"trace" => std::result::Result::Ok(FrontendLogLevel::Trace),
|
||||
"debug" => std::result::Result::Ok(FrontendLogLevel::Debug),
|
||||
"info" => std::result::Result::Ok(FrontendLogLevel::Info),
|
||||
"warn" => std::result::Result::Ok(FrontendLogLevel::Warn),
|
||||
"error" => std::result::Result::Ok(FrontendLogLevel::Error),
|
||||
_ => std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_FRONTEND_LOG_LEVEL_INVALID, "Frontend log level is not supported")),
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_target(target_id: &str) -> ksp_core_lib::Result<FrontendLogTarget> {
|
||||
return match target_id.trim().to_ascii_lowercase().as_str() {
|
||||
"frontend" => std::result::Result::Ok(FrontendLogTarget::Frontend),
|
||||
"main" => std::result::Result::Ok(FrontendLogTarget::Main),
|
||||
"splash" => std::result::Result::Ok(FrontendLogTarget::Splash),
|
||||
_ => {
|
||||
std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_FRONTEND_LOG_TARGET_INVALID, "Frontend log target identifier is not supported"))
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn emit_validated_frontend_log(level: FrontendLogLevel, target: FrontendLogTarget, message: &str) {
|
||||
return match target {
|
||||
FrontendLogTarget::Frontend => emit_frontend_target(level, message),
|
||||
FrontendLogTarget::Main => emit_main_target(level, message),
|
||||
FrontendLogTarget::Splash => emit_splash_target(level, message),
|
||||
};
|
||||
}
|
||||
|
||||
fn emit_frontend_target(level: FrontendLogLevel, message: &str) {
|
||||
return match level {
|
||||
FrontendLogLevel::Trace => ksp_logging_lib::trace!(
|
||||
target: crate::TRACING_TARGET_FRONTEND,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "frontend",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Debug => ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET_FRONTEND,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "frontend",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Info => ksp_logging_lib::info!(
|
||||
target: crate::TRACING_TARGET_FRONTEND,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "frontend",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Warn => ksp_logging_lib::warn!(
|
||||
target: crate::TRACING_TARGET_FRONTEND,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "frontend",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Error => ksp_logging_lib::error!(
|
||||
target: crate::TRACING_TARGET_FRONTEND,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "frontend",
|
||||
"{message}"
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn emit_main_target(level: FrontendLogLevel, message: &str) {
|
||||
return match level {
|
||||
FrontendLogLevel::Trace => ksp_logging_lib::trace!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_MAIN,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "main",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Debug => ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_MAIN,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "main",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Info => ksp_logging_lib::info!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_MAIN,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "main",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Warn => ksp_logging_lib::warn!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_MAIN,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "main",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Error => ksp_logging_lib::error!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_MAIN,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "main",
|
||||
"{message}"
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn emit_splash_target(level: FrontendLogLevel, message: &str) {
|
||||
return match level {
|
||||
FrontendLogLevel::Trace => ksp_logging_lib::trace!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_SPLASH,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "splash",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Debug => ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_SPLASH,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "splash",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Info => ksp_logging_lib::info!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_SPLASH,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "splash",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Warn => ksp_logging_lib::warn!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_SPLASH,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "splash",
|
||||
"{message}"
|
||||
),
|
||||
FrontendLogLevel::Error => ksp_logging_lib::error!(
|
||||
target: crate::TRACING_TARGET_FRONTEND_SPLASH,
|
||||
domain = crate::TRACING_DOMAIN_FRONTEND,
|
||||
action = "frontend_log",
|
||||
target_id = "splash",
|
||||
"{message}"
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/frontend_logging.rs"]
|
||||
mod tests;
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/lib.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
//! Tauri desktop application for managing and validating KSP configuration.
|
||||
|
||||
@@ -12,6 +12,7 @@ mod bootstrap;
|
||||
mod constants;
|
||||
mod dto_common;
|
||||
mod errors;
|
||||
mod frontend_logging;
|
||||
mod tauri;
|
||||
|
||||
/// Runs the KSP configuration desktop application.
|
||||
@@ -21,10 +22,18 @@ pub(crate) use self::app_state::AppState;
|
||||
pub(crate) use self::bootstrap::config_management;
|
||||
pub(crate) use self::bootstrap::initialize_logging;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_BOOTSTRAP;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_FRONTEND;
|
||||
pub(crate) use self::constants::TRACING_TARGET;
|
||||
pub(crate) use self::constants::TRACING_TARGET_FRONTEND;
|
||||
pub(crate) use self::constants::TRACING_TARGET_FRONTEND_MAIN;
|
||||
pub(crate) use self::constants::TRACING_TARGET_FRONTEND_SPLASH;
|
||||
pub(crate) use self::dto_common::AppSnapshotDto;
|
||||
pub(crate) use self::dto_common::CommandErrorDto;
|
||||
pub(crate) use self::errors::ERROR_CODE_APP_STATE_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_APP_STATE_LOCK_FAILED;
|
||||
pub(crate) use self::errors::ERROR_CODE_FRONTEND_LOG_LEVEL_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_FRONTEND_LOG_TARGET_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_LOGGING_BOOTSTRAP_FAILED;
|
||||
pub(crate) use self::errors::ERROR_CODE_TAURI_RUNTIME_FAILED;
|
||||
pub(crate) use self::frontend_logging::FrontendLogPayloadDto;
|
||||
pub(crate) use self::frontend_logging::emit_frontend_log_event;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/tauri.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
//! Tauri runtime assembly for the KSP configuration desktop application.
|
||||
|
||||
@@ -38,7 +38,7 @@ fn configure_plugins(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<taur
|
||||
}
|
||||
|
||||
fn configure_commands(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
|
||||
return builder.invoke_handler(tauri::generate_handler![get_app_snapshot]);
|
||||
return builder.invoke_handler(tauri::generate_handler![get_app_snapshot, emit_frontend_log]);
|
||||
}
|
||||
|
||||
fn configure_setup(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
|
||||
@@ -61,3 +61,12 @@ fn get_app_snapshot(state: tauri::State<'_, crate::AppState>) -> std::result::Re
|
||||
std::result::Result::Err(error) => std::result::Result::Err(crate::CommandErrorDto::from_error(&error)),
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn emit_frontend_log(payload: crate::FrontendLogPayloadDto) -> std::result::Result<(), crate::CommandErrorDto> {
|
||||
let result = crate::emit_frontend_log_event(payload);
|
||||
return match result {
|
||||
std::result::Result::Ok(()) => std::result::Result::Ok(()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(crate::CommandErrorDto::from_error(&error)),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user