//! Strongly-typed identifiers. //! //! Each identifier is a `newtype` around [`uuid::Uuid`]. Using distinct types //! per concept makes it impossible to pass, say, an [`AgentId`] where a //! [`ProjectId`] is expected (compile-time safety, SOLID/typing discipline). use serde::{Deserialize, Serialize}; use uuid::Uuid; macro_rules! typed_id { ($(#[$meta:meta])* $name:ident) => { $(#[$meta])* #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[serde(transparent)] pub struct $name(pub Uuid); impl $name { /// Wraps an existing [`Uuid`]. #[must_use] pub const fn from_uuid(id: Uuid) -> Self { Self(id) } /// Generates a fresh random (v4) identifier. /// /// Prefer injecting an [`crate::ports::IdGenerator`] in application /// code for determinism; this convenience exists for tests and the /// composition root. #[must_use] pub fn new_random() -> Self { Self(Uuid::new_v4()) } /// Returns the inner [`Uuid`]. #[must_use] pub const fn as_uuid(&self) -> Uuid { self.0 } } impl std::fmt::Display for $name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl From for $name { fn from(id: Uuid) -> Self { Self(id) } } }; } typed_id!( /// Identifies a [`crate::project::Project`]. ProjectId ); typed_id!( /// Identifies an [`crate::agent::Agent`]. AgentId ); typed_id!( /// Identifies an [`crate::template::AgentTemplate`]. TemplateId ); typed_id!( /// Identifies an [`crate::profile::AgentProfile`]. ProfileId ); typed_id!( /// Identifies a [`crate::skill::Skill`]. SkillId ); typed_id!( /// Identifies a [`crate::terminal::TerminalSession`]. SessionId ); typed_id!( /// Identifies a [`crate::layout::WindowId`]-bearing OS window. WindowId ); typed_id!( /// Identifies a [`crate::layout::Tab`]. TabId ); typed_id!( /// Identifies one named terminal layout within a project (L10/#4). LayoutId ); typed_id!( /// Identifies a node in a [`crate::layout::LayoutTree`]. NodeId ); typed_id!( /// Identifies one armed one-shot wake-up of a [`crate::ports::Scheduler`] /// (ARCHITECTURE ยง21.4). Opaque, cancellable handle returned by /// [`crate::ports::Scheduler::arm`] and consumed by /// [`crate::ports::Scheduler::cancel`]. ScheduleId );