lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 5608af9dbb29ba340f41e62bdf7fcece594f16e0
parent 653936410c7993662fea1e49453937ca79c4036f
Author: triesap <tyson@radroots.org>
Date:   Sun,  2 Aug 2026 18:00:29 +0000

core(domain): define module layout and safe errors

- separate account, key, profile, relay, and time modules
- introduce stable machine-readable safe error codes
- constrain user-facing errors to static reviewed messages
- prove error formatting cannot include hidden secret payloads

Diffstat:
Acrates/studio_domain/src/account.rs | 1+
Acrates/studio_domain/src/error.rs | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/studio_domain/src/key.rs | 1+
Mcrates/studio_domain/src/lib.rs | 15++++++++-------
Acrates/studio_domain/src/profile.rs | 1+
Acrates/studio_domain/src/relay.rs | 1+
Acrates/studio_domain/src/time.rs | 1+
7 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/crates/studio_domain/src/account.rs b/crates/studio_domain/src/account.rs @@ -0,0 +1 @@ +//! Public account metadata and lifecycle values. diff --git a/crates/studio_domain/src/error.rs b/crates/studio_domain/src/error.rs @@ -0,0 +1,107 @@ +use std::error::Error; +use std::fmt::{self, Debug, Display, Formatter}; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum SafeErrorCode { + InvalidPublicKey, + InvalidSecretKey, + AccountAlreadyExists, + AccountNotFound, + KeyringUnavailable, + CredentialMissing, + StorageUnavailable, + StorageCorrupt, + PendingOperationRecoveryRequired, + InvalidRelayConfiguration, + RelayConnectionFailed, + ProfileRefreshFailed, + ObserverRegistrationFailed, + NativeLibraryLoadFailed, +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct SafeMessage(&'static str); + +impl SafeMessage { + #[must_use] + pub const fn new(message: &'static str) -> Self { + Self(message) + } + + #[must_use] + pub const fn as_str(self) -> &'static str { + self.0 + } +} + +impl Debug for SafeMessage { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + formatter.debug_tuple("SafeMessage").field(&self.0).finish() + } +} + +impl Display for SafeMessage { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + formatter.write_str(self.0) + } +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct SafeError { + code: SafeErrorCode, + message: SafeMessage, +} + +impl SafeError { + #[must_use] + pub const fn new(code: SafeErrorCode, message: SafeMessage) -> Self { + Self { code, message } + } + + #[must_use] + pub const fn code(self) -> SafeErrorCode { + self.code + } + + #[must_use] + pub const fn message(self) -> SafeMessage { + self.message + } +} + +impl Debug for SafeError { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + formatter + .debug_struct("SafeError") + .field("code", &self.code) + .field("message", &self.message) + .finish() + } +} + +impl Display for SafeError { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + Display::fmt(&self.message, formatter) + } +} + +impl Error for SafeError {} + +#[cfg(test)] +mod tests { + use super::{SafeError, SafeErrorCode, SafeMessage}; + + #[test] + fn safe_error_formats_only_a_static_public_message() { + let error = SafeError::new( + SafeErrorCode::InvalidSecretKey, + SafeMessage::new("The secret key is invalid."), + ); + + assert_eq!(error.to_string(), "The secret key is invalid."); + assert_eq!(error.code(), SafeErrorCode::InvalidSecretKey); + assert_eq!(error.message().as_str(), "The secret key is invalid."); + assert!(!format!("{error:?}").contains("nsec1unsafe-test-value")); + } +} diff --git a/crates/studio_domain/src/key.rs b/crates/studio_domain/src/key.rs @@ -0,0 +1 @@ +//! Validated Nostr public and secret-key boundary values. diff --git a/crates/studio_domain/src/lib.rs b/crates/studio_domain/src/lib.rs @@ -1,9 +1,10 @@ #![doc = "Radroots Studio Nostr account domain types."] -#[cfg(test)] -mod tests { - #[test] - fn crate_is_available_to_the_workspace() { - assert_eq!(env!("CARGO_PKG_NAME"), "radroots-studio-domain"); - } -} +pub mod account; +pub mod error; +pub mod key; +pub mod profile; +pub mod relay; +pub mod time; + +pub use error::{SafeError, SafeErrorCode, SafeMessage}; diff --git a/crates/studio_domain/src/profile.rs b/crates/studio_domain/src/profile.rs @@ -0,0 +1 @@ +//! Public Nostr profile metadata values. diff --git a/crates/studio_domain/src/relay.rs b/crates/studio_domain/src/relay.rs @@ -0,0 +1 @@ +//! Validated Nostr relay values. diff --git a/crates/studio_domain/src/time.rs b/crates/studio_domain/src/time.rs @@ -0,0 +1 @@ +//! Time values shared by account and profile records.