shepherd-rs 0.2.0

Shepherd is a resilient, non-blocking orchestrator that persistently transforms and delivers data—built for remote, compute-heavy workloads.
Documentation
//! # Mock Transformations
//! 
//! This module provides mock implementations for transformation requests and attempts.
//! 
//! ## Overview
//! - **MockTransformRequest**: Represents a mock transformation request.
//! - **MockTransformAttempt**: Represents a mock transformation attempt.
//! 
//! ## Example
//! ```rust
//! let mock_request = MockTransformRequest::new(...);
//! let mock_attempt = MockTransformAttempt::new(...);
//! ```

use std::collections::HashMap;

use async_trait::async_trait;
use thiserror::Error;

use crate::transform::{TransformAttempt, TransformAttemptCreator, TransformRequest};

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct MockTransformRequest {
    pub(crate) request_id: u64,
    pub(crate) input: String,
    pub(crate) output: String,
}

impl MockTransformRequest {
    pub(crate) fn new(request_id: u64, input: impl ToString, output: impl ToString) -> Self {
        Self {
            request_id,
            input: input.to_string(),
            output: output.to_string(),
        }
    }
}

impl TransformRequest for MockTransformRequest {
    type Identifier = u64;
    type Input = String;
    type Output = String;

    fn request_id(&self) -> Self::Identifier { self.request_id }

    fn input(&self) -> &Self::Input { &self.input }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct MockTransformAttempt {
    pub(crate) attempt_id: (u64, u64),
    pub(crate) send_ctx: String,
    pub(crate) send_val: String,
}

#[derive(Error, Debug)]
pub(crate) enum MockTransformError {
    #[error("Mock transform error occurred")]
    MockError,
}

impl TransformAttempt for MockTransformAttempt {
    type Identifier = (u64, u64);
    type ReturnCtx = String;
    type ReturnVal = String;
    type SendCtx = String;
    type SendVal = String;
    type TransformError = MockTransformError;

    fn new(attempt_id: Self::Identifier, send_ctx: Self::SendCtx, send_val: Self::SendVal) -> Self {
        Self {
            attempt_id,
            send_ctx,
            send_val,
        }
    }

    fn send_package(&self) -> Self::SendPackage {
        (
            self.attempt_id,
            self.send_ctx.clone(),
            self.send_val.clone(),
        )
    }
}

pub(crate) struct MockAttemptCreator<TR, TA, IN, OUT>
where
    TR: TransformRequest<Identifier = u64, Input = IN, Output = OUT>,
    TA: TransformAttempt<
            Identifier = (u64, u64),
            SendCtx = String,
            SendVal = IN,
            ReturnCtx = String,
            ReturnVal = OUT,
            TransformError = MockTransformError,
        >,
    IN: Clone + Send,
    OUT: Clone + Send,
{
    pub(crate) attempts_list: HashMap<TR::Identifier, Vec<TA>>,
}

#[async_trait]
impl<TR, TA, IN, OUT> TransformAttemptCreator for MockAttemptCreator<TR, TA, IN, OUT>
where
    TR: TransformRequest<Identifier = u64, Input = IN, Output = OUT>,
    TA: TransformAttempt<
            Identifier = (u64, u64),
            SendCtx = String,
            SendVal = IN,
            ReturnCtx = String,
            ReturnVal = OUT,
            TransformError = MockTransformError,
        >,
    IN: Clone + Send,
    OUT: Clone + Send,
{
    type Input = IN;
    type Output = OUT;
    type TransformAttempt = TA;
    type TransformRequest = TR;

    fn new(capacity: usize) -> Self {
        Self {
            attempts_list: HashMap::with_capacity(capacity),
        }
    }

    async fn create_new_attempt(
        &mut self,
        request: &Self::TransformRequest,
    ) -> Self::TransformAttempt {
        let attempt_id = self
            .attempts_list
            .get(&request.request_id())
            .map_or(0, |attempts| attempts.len() as u64);

        let attempt = Self::TransformAttempt::new(
            (request.request_id(), attempt_id),
            String::from("mock_call_config"),
            request.input().clone(),
        );

        self.attempts_list
            .entry(request.request_id())
            .or_default()
            .push(attempt.clone());

        attempt
    }
}