v0.1.4-pre.015
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
// file: crates/ksp-app-config-desk/src/logging_editor.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Read-only typed Logging document projection for the Config Desk Logging editor.
|
||||
//! Typed Logging document projection and validated persistence for the Config Desk Logging editor.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
/// One Logging sink selector/filter exposed to the read-only editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
/// One Logging sink selector/filter exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingOutputFilterDto.ts")]
|
||||
pub(crate) struct LoggingOutputFilterDto {
|
||||
@@ -18,8 +18,8 @@ pub(crate) struct LoggingOutputFilterDto {
|
||||
pub(crate) domains: std::vec::Vec<String>,
|
||||
}
|
||||
|
||||
/// Console sink configuration exposed to the read-only editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
/// Console sink configuration exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingConsoleDto.ts")]
|
||||
pub(crate) struct LoggingConsoleDto {
|
||||
@@ -35,8 +35,8 @@ pub(crate) struct LoggingConsoleDto {
|
||||
pub(crate) filter: LoggingOutputFilterDto,
|
||||
}
|
||||
|
||||
/// One persistent file sink exposed to the read-only editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
/// One persistent file sink exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingFileDto.ts")]
|
||||
pub(crate) struct LoggingFileDto {
|
||||
@@ -56,8 +56,8 @@ pub(crate) struct LoggingFileDto {
|
||||
pub(crate) filter: LoggingOutputFilterDto,
|
||||
}
|
||||
|
||||
/// One global Logging target override exposed to the read-only editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
/// One global Logging target override exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingTargetFilterDto.ts")]
|
||||
pub(crate) struct LoggingTargetFilterDto {
|
||||
@@ -67,8 +67,8 @@ pub(crate) struct LoggingTargetFilterDto {
|
||||
pub(crate) level: String,
|
||||
}
|
||||
|
||||
/// One typed Logging profile exposed to the read-only editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
/// One typed Logging profile exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingProfileDto.ts")]
|
||||
pub(crate) struct LoggingProfileDto {
|
||||
@@ -86,7 +86,7 @@ pub(crate) struct LoggingProfileDto {
|
||||
pub(crate) target_filters: std::vec::Vec<LoggingTargetFilterDto>,
|
||||
}
|
||||
|
||||
/// Complete typed Logging document exposed to the read-only editor.
|
||||
/// Complete typed Logging document exposed to the editor.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingDocumentDto.ts")]
|
||||
@@ -105,11 +105,66 @@ pub(crate) struct LoggingDocumentDto {
|
||||
pub(crate) profiles: std::vec::Vec<LoggingProfileDto>,
|
||||
}
|
||||
|
||||
/// Complete editable Logging candidate accepted from the frontend.
|
||||
#[derive(Clone, Debug, serde::Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingDocumentCandidateDto.ts")]
|
||||
pub(crate) struct LoggingDocumentCandidateDto {
|
||||
/// Source Logging root expression/path.
|
||||
pub(crate) logs_directory: String,
|
||||
/// Autonomous default profile identifier.
|
||||
pub(crate) default_profile: String,
|
||||
/// Typed profiles in source order.
|
||||
pub(crate) profiles: std::vec::Vec<LoggingProfileDto>,
|
||||
}
|
||||
|
||||
/// Result of one validated typed Logging persistence operation.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging/LoggingDocumentSaveResultDto.ts")]
|
||||
pub(crate) struct LoggingDocumentSaveResultDto {
|
||||
/// Whether `std.logging.json` bytes changed.
|
||||
pub(crate) source_changed: bool,
|
||||
/// Whether Config consumers must reload the document.
|
||||
pub(crate) reload_required: bool,
|
||||
/// Fresh typed document loaded after successful persistence.
|
||||
pub(crate) document: LoggingDocumentDto,
|
||||
}
|
||||
|
||||
/// Loads the typed Logging source through ConfigManagement and projects it for the frontend.
|
||||
pub(crate) fn document(state: &crate::AppState) -> ksp_core_lib::Result<LoggingDocumentDto> {
|
||||
return document_from_management(state.config_management());
|
||||
}
|
||||
|
||||
/// Validates and atomically persists one typed Logging candidate through ConfigManagement.
|
||||
pub(crate) fn save(state: &crate::AppState, candidate: LoggingDocumentCandidateDto) -> ksp_core_lib::Result<LoggingDocumentSaveResultDto> {
|
||||
let source = config_candidate(candidate);
|
||||
let report = state.config_management().save_logging_document(&source);
|
||||
let report = match report {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let document = document_from_management(state.config_management());
|
||||
let document = match document {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_LOGGING_EDITOR,
|
||||
source_changed = report.source_changed(),
|
||||
reload_required = report.reload_required(),
|
||||
profile_count = document.profiles.len(),
|
||||
default_profile = document.default_profile.as_str(),
|
||||
"typed Logging document persistence completed; runtime was not reinitialized"
|
||||
);
|
||||
return std::result::Result::Ok(LoggingDocumentSaveResultDto {
|
||||
source_changed: report.source_changed(),
|
||||
reload_required: report.reload_required(),
|
||||
document,
|
||||
});
|
||||
}
|
||||
|
||||
fn document_from_management(management: &ksp_config_lib::ConfigManagement) -> ksp_core_lib::Result<LoggingDocumentDto> {
|
||||
let source = management.load_logging_document();
|
||||
let source = match source {
|
||||
@@ -149,11 +204,51 @@ fn document_from_management(management: &ksp_config_lib::ConfigManagement) -> ks
|
||||
profile_count = result.profiles.len(),
|
||||
file_count,
|
||||
target_filter_count,
|
||||
"typed Logging document projected for read-only editor"
|
||||
"typed Logging document projected for editor"
|
||||
);
|
||||
return std::result::Result::Ok(result);
|
||||
}
|
||||
|
||||
fn config_candidate(candidate: LoggingDocumentCandidateDto) -> ksp_config_lib::LoggingConfigDocument {
|
||||
let mut profiles = std::vec::Vec::<ksp_config_lib::LoggingProfileConfig>::with_capacity(candidate.profiles.len());
|
||||
for profile in candidate.profiles {
|
||||
profiles.push(config_profile(profile));
|
||||
}
|
||||
return ksp_config_lib::LoggingConfigDocument::new(candidate.logs_directory, candidate.default_profile, profiles);
|
||||
}
|
||||
|
||||
fn config_profile(profile: LoggingProfileDto) -> ksp_config_lib::LoggingProfileConfig {
|
||||
let mut files = std::vec::Vec::<ksp_config_lib::LoggingFileConfig>::with_capacity(profile.files.len());
|
||||
for file in profile.files {
|
||||
let mut config =
|
||||
ksp_config_lib::LoggingFileConfig::new(file.output_id, file.enabled, file.path, file.rotation, file.format, config_output_filter(file.filter));
|
||||
config.set_ansi(file.ansi);
|
||||
files.push(config);
|
||||
}
|
||||
let mut target_filters = std::vec::Vec::<ksp_config_lib::LoggingTargetFilterConfig>::with_capacity(profile.target_filters.len());
|
||||
for target_filter in profile.target_filters {
|
||||
target_filters.push(ksp_config_lib::LoggingTargetFilterConfig::new(target_filter.target_prefix, target_filter.level));
|
||||
}
|
||||
return ksp_config_lib::LoggingProfileConfig::new(
|
||||
profile.profile_id,
|
||||
profile.default_filter,
|
||||
profile.span_events,
|
||||
ksp_config_lib::LoggingConsoleConfig::new(
|
||||
profile.console.enabled,
|
||||
profile.console.output,
|
||||
profile.console.ansi,
|
||||
profile.console.format,
|
||||
config_output_filter(profile.console.filter),
|
||||
),
|
||||
files,
|
||||
target_filters,
|
||||
);
|
||||
}
|
||||
|
||||
fn config_output_filter(filter: LoggingOutputFilterDto) -> ksp_config_lib::LoggingOutputFilterConfig {
|
||||
return ksp_config_lib::LoggingOutputFilterConfig::new(filter.level, filter.targets, filter.domains);
|
||||
}
|
||||
|
||||
fn project_profile(profile: &ksp_config_lib::LoggingProfileConfig) -> LoggingProfileDto {
|
||||
let mut files = std::vec::Vec::<LoggingFileDto>::with_capacity(profile.files().len());
|
||||
for file in profile.files() {
|
||||
|
||||
Reference in New Issue
Block a user