Files
khadhroony-solana-project/crates/ksp-logging-lib/src/identity.rs

73 lines
2.9 KiB
Rust

// file: crates/ksp-logging-lib/src/identity.rs
// version: 2
//! Stable runtime identity used to separate persistent file outputs between application launches.
/// Identity attached to one installed KSP Logging runtime for the lifetime of an application launch.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LoggingRuntimeIdentity {
application_id: std::string::String,
launch_timestamp: std::string::String,
}
impl LoggingRuntimeIdentity {
/// Creates a validated runtime identity from an application identifier and launch timestamp token.
pub fn new(
application_id: impl std::convert::Into<std::string::String>,
launch_timestamp: impl std::convert::Into<std::string::String>,
) -> ksp_core_lib::Result<Self> {
let application_id = application_id.into();
let launch_timestamp = launch_timestamp.into();
let application_validation = validate_identity_component(application_id.as_str(), "application_id");
if let std::result::Result::Err(error) = application_validation {
return std::result::Result::Err(error);
}
let timestamp_validation = validate_identity_component(launch_timestamp.as_str(), "launch_timestamp");
if let std::result::Result::Err(error) = timestamp_validation {
return std::result::Result::Err(error);
}
return std::result::Result::Ok(Self { application_id, launch_timestamp });
}
/// Returns the application identifier embedded in persistent runtime file names.
#[must_use]
pub fn application_id(&self) -> &str {
return self.application_id.as_str();
}
/// Returns the stable launch timestamp token embedded in persistent runtime file names.
#[must_use]
pub fn launch_timestamp(&self) -> &str {
return self.launch_timestamp.as_str();
}
/// Executes the crate-internal file name prefix operation for `LoggingRuntimeIdentity`.
pub(crate) fn file_name_prefix(&self, configured_prefix: &str) -> std::string::String {
return format!("{}.{}.{}", self.application_id, self.launch_timestamp, configured_prefix);
}
}
fn validate_identity_component(value: &str, field: &'static str) -> ksp_core_lib::Result<()> {
if value.is_empty() || value.len() > 160 {
return invalid_identity(field);
}
for byte in value.bytes() {
let accepted = byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-');
if !accepted {
return invalid_identity(field);
}
}
return std::result::Result::Ok(());
}
fn invalid_identity(field: &'static str) -> ksp_core_lib::Result<()> {
return std::result::Result::Err(
ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_RUNTIME_IDENTITY, "KSP Logging runtime identity contains an invalid component")
.with_context("field", field),
);
}
#[cfg(test)]
#[path = "../unit_tests/identity.rs"]
mod tests;