Files
khadhroony-solana-project/crates/ksp-worker-api/src/identity.rs

77 lines
2.8 KiB
Rust

// file: crates/ksp-worker-api/src/identity.rs
// version: 2
/// Maximum UTF-8 byte length admitted for one Worker identifier.
pub const MAX_WORKER_ID_BYTES: usize = 128;
/// Maximum UTF-8 byte length admitted for one Worker kind code.
pub const MAX_WORKER_KIND_CODE_BYTES: usize = 128;
/// Bounded caller-supplied identity of one logical Worker instance.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WorkerId(std::string::String);
impl crate::WorkerId {
/// Creates one non-empty Worker identifier using the KSP safe-code alphabet.
pub fn new(value: impl std::convert::Into<std::string::String>) -> crate::Result<Self> {
let value = value.into();
if !valid_worker_code(value.as_str(), crate::MAX_WORKER_ID_BYTES) {
return std::result::Result::Err(identity_error(crate::ERROR_CODE_WORKER_ID_INVALID, "worker_id"));
}
return std::result::Result::Ok(Self(value));
}
/// Returns the validated Worker identifier.
#[must_use]
pub fn as_str(&self) -> &str {
return self.0.as_str();
}
}
impl std::fmt::Debug for crate::WorkerId {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str("WorkerId(..)");
}
}
/// Bounded stable code identifying one concrete family of Workers.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WorkerKindCode(std::string::String);
impl crate::WorkerKindCode {
/// Creates one non-empty Worker kind using the KSP safe-code alphabet.
pub fn new(value: impl std::convert::Into<std::string::String>) -> crate::Result<Self> {
let value = value.into();
if !valid_worker_code(value.as_str(), crate::MAX_WORKER_KIND_CODE_BYTES) {
return std::result::Result::Err(identity_error(crate::ERROR_CODE_WORKER_KIND_INVALID, "worker_kind"));
}
return std::result::Result::Ok(Self(value));
}
/// Returns the validated stable Worker kind code.
#[must_use]
pub fn as_str(&self) -> &str {
return self.0.as_str();
}
}
impl std::fmt::Debug for crate::WorkerKindCode {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.debug_tuple("WorkerKindCode").field(&self.0).finish();
}
}
fn identity_error(code: crate::ErrorCode, field: &'static str) -> crate::Error {
return crate::Error::new(code, "invalid bounded Worker identity").with_context("field", field);
}
fn valid_worker_code(value: &str, maximum_len: usize) -> bool {
if value.is_empty() || value.len() > maximum_len {
return false;
}
return value.bytes().all(|byte| return byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-' | b'.' | b':'));
}
#[cfg(test)]
#[path = "../unit_tests/identity.rs"]
mod tests;