sidebyside-core 0.1.0

Core domain types for Sidebyside SDK
Documentation
//! Workflow definition traits
//!
//! This module defines the traits for workflow definitions.

use serde::{de::DeserializeOwned, Serialize};
use std::future::Future;
use std::pin::Pin;

use crate::error::CoreError;
use crate::ids::WorkflowId;

/// A trait for defining workflow types
///
/// Workflows are the main unit of execution in Sidebyside. They define
/// the orchestration logic that coordinates activities and decision points.
pub trait WorkflowDefinition: Send + Sync {
    /// The input type for this workflow
    type Input: Serialize + DeserializeOwned + Send + Sync;
    /// The output type for this workflow
    type Output: Serialize + DeserializeOwned + Send + Sync;

    /// Get the workflow type name
    fn workflow_type() -> &'static str;

    /// Run the workflow with the given context and input
    fn run(
        &self,
        ctx: WorkflowContext,
        input: Self::Input,
    ) -> Pin<Box<dyn Future<Output = Result<Self::Output, CoreError>> + Send + '_>>;
}

/// Context provided to workflows during execution
#[derive(Debug, Clone)]
pub struct WorkflowContext {
    /// The workflow ID
    pub workflow_id: WorkflowId,
    /// Whether this is a replay of a previous execution
    pub is_replaying: bool,
    /// Current attempt number
    pub attempt: u32,
}

impl WorkflowContext {
    /// Create a new workflow context
    #[must_use]
    pub fn new(workflow_id: WorkflowId) -> Self {
        Self {
            workflow_id,
            is_replaying: false,
            attempt: 1,
        }
    }

    /// Check if the workflow is replaying
    #[must_use]
    pub fn is_replaying(&self) -> bool {
        self.is_replaying
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_workflow_context_creation() {
        let ctx = WorkflowContext::new(WorkflowId::generate());
        assert!(!ctx.is_replaying());
        assert_eq!(ctx.attempt, 1);
    }
}