plexor-core 0.1.0-alpha.2

Core library for the rust implementation of the Plexo distributed system architecture, providing the fundamental Plexus, Neuron, Codec, and Axon abstractions.
Documentation
// Copyright 2025 Alecks Gates
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use crate::codec::{Codec, CodecName};
use crate::erasure::reactant::{ErrorReactantErased, ReactantErased, ReactantRawErased};
use crate::payload::{Payload, PayloadRaw};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum ReactantError {
    #[error("Reactant execution failed: {0}")]
    Execution(String),
    #[error(transparent)]
    Other(#[from] Box<dyn std::error::Error + Send + Sync>),
}

pub trait Reactant<T, C>
where
    C: Codec<T> + CodecName + Send + Sync + 'static,
    T: Send + Sync + 'static,
    Self: Send + Sync,
{
    fn react(
        &self,
        payload: Arc<Payload<T, C>>,
    ) -> Pin<Box<dyn Future<Output = Result<(), ReactantError>> + Send + 'static>>;

    fn erase(self: Box<Self>) -> Arc<dyn ReactantErased + Send + Sync + 'static>;

    /// Helper to consume this reactant and return an erased Arc.
    fn new_erased(self) -> Arc<dyn ReactantErased + Send + Sync + 'static>
    where
        Self: Sized + 'static,
    {
        Box::new(self).erase()
    }
}

pub trait ReactantRaw<T, C>
where
    C: Codec<T> + CodecName + Send + Sync + 'static,
    T: Send + Sync + 'static,
    Self: Send + Sync,
{
    fn react(
        &self,
        payload: Arc<PayloadRaw<T, C>>,
    ) -> Pin<Box<dyn Future<Output = Result<(), ReactantError>> + Send + 'static>>;

    fn erase_raw(self: Box<Self>) -> Arc<dyn ReactantRawErased + Send + Sync + 'static>;

    /// Helper to consume this reactant and return an erased Arc.
    fn new_erased_raw(self) -> Arc<dyn ReactantRawErased + Send + Sync + 'static>
    where
        Self: Sized + 'static,
    {
        Box::new(self).erase_raw()
    }
}

pub trait ErrorReactant<T, C>: Send + Sync
where
    C: Codec<T> + CodecName + Send + Sync + 'static,
    T: Send + Sync + 'static,
{
    fn react_error(
        &self,
        error: Arc<ReactantError>,
        payload: Arc<Payload<T, C>>,
    ) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>;

    fn erase_error(self: Box<Self>) -> Arc<dyn ErrorReactantErased + Send + Sync + 'static>;

    /// Helper to consume this error reactant and return an erased Arc.
    fn new_erased_error(self) -> Arc<dyn ErrorReactantErased + Send + Sync + 'static>
    where
        Self: Sized + 'static,
    {
        Box::new(self).erase_error()
    }
}