Introduit l'abstraction de planification pour la reprise différée à la levée d'une limite de session : - domaine : trait Scheduler + enum ScheduledTask (ports.rs), ScheduleId via typed_id! (ids.rs), re-exports (lib.rs). - infra : TokioScheduler (scheduler/mod.rs, nouveau) + pub mod scheduler et re-export (lib.rs). Tests QA inline (#[cfg(test)]) : 7 tests scheduler (3× sans flaky). `cargo test -p infrastructure` = 195 passed / 0 failed ; domaine + infra builds 0 warning ; LS1/LS2 toujours verts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
2.7 KiB
Rust
102 lines
2.7 KiB
Rust
//! 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<Uuid> 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
|
|
);
|