frame-conv 0.2.0

Conversation patterns — request-response, subscription, pub/sub, and workflow over liminal
Documentation
//! Workflow conversation identity — the caller-persistable names for one
//! aion workflow/run lineage.
//!
//! These are the bytes a caller holds to reconstruct a
//! [`super::WorkflowConversation`] after restart (the R2
//! reconstruct-from-held-ids path). frame-conv persists nothing; the
//! caller owns where these live.

use std::fmt;

use uuid::Uuid;

/// Identity of one durable workflow conversation (aion's workflow id,
/// spoken in conversation vocabulary).
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct WorkflowConversationId(Uuid);

impl WorkflowConversationId {
    /// Reconstructs an identity from caller-held bytes.
    #[must_use]
    pub const fn from_bytes(bytes: [u8; 16]) -> Self {
        Self(Uuid::from_bytes(bytes))
    }

    /// Returns the bytes a caller persists to name this conversation later.
    #[must_use]
    pub const fn to_bytes(self) -> [u8; 16] {
        *self.0.as_bytes()
    }

    pub(crate) const fn from_uuid(id: Uuid) -> Self {
        Self(id)
    }

    pub(crate) const fn as_uuid(self) -> Uuid {
        self.0
    }
}

impl fmt::Display for WorkflowConversationId {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

/// Identity of one concrete run of a workflow conversation. Reopen and
/// continue-as-new advance the run while the conversation id persists.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct WorkflowRunId(Uuid);

impl WorkflowRunId {
    /// Reconstructs a run identity from caller-held bytes.
    #[must_use]
    pub const fn from_bytes(bytes: [u8; 16]) -> Self {
        Self(Uuid::from_bytes(bytes))
    }

    /// Returns the bytes a caller persists to name this run later.
    #[must_use]
    pub const fn to_bytes(self) -> [u8; 16] {
        *self.0.as_bytes()
    }

    pub(crate) const fn from_uuid(id: Uuid) -> Self {
        Self(id)
    }

    pub(crate) const fn as_uuid(self) -> Uuid {
        self.0
    }
}

impl fmt::Display for WorkflowRunId {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

/// The full caller-persistable identity: conversation plus current run.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct WorkflowIdentity {
    /// The durable conversation (aion workflow) identity.
    pub conversation: WorkflowConversationId,
    /// The concrete run this handle was opened or reconstructed against.
    pub run: WorkflowRunId,
}

/// Identity of one step (aion activity) within a run's history, derived
/// deterministically from its scheduling sequence position.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct WorkflowStepId(u64);

impl WorkflowStepId {
    /// Returns the scheduling sequence position naming this step.
    #[must_use]
    pub const fn position(self) -> u64 {
        self.0
    }

    pub(crate) const fn from_position(position: u64) -> Self {
        Self(position)
    }
}

impl fmt::Display for WorkflowStepId {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(formatter, "step:{}", self.0)
    }
}