use core::future::Future;
use behavior::{Address, BirthMode, Births, Create, Never, NoBirths};
pub(crate) trait SealedChildRuntime {}
pub(crate) trait SealedBirthMode {}
impl SealedBirthMode for NoBirths {}
impl<C> SealedBirthMode for Births<C> {}
#[allow(
private_bounds,
reason = "sealing supertrait is deliberately crate-private"
)]
#[doc(hidden)]
pub trait ChildRuntime<A: Address, B, S>: SealedChildRuntime {
type Lease: super::CoordinatedChild;
type Error;
fn birth(
&self,
parent: A,
child: Create<A, B>,
response: S,
) -> impl Future<Output = Result<Self::Lease, Self::Error>> + Send;
}
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct NoChildren(());
impl SealedChildRuntime for NoChildren {}
impl NoChildren {
pub(crate) const fn new() -> Self {
Self(())
}
}
impl<A, S> ChildRuntime<A, Never, S> for NoChildren
where
A: Address + Send,
A::Nonce: Send,
S: Send,
{
type Lease = Never;
type Error = Never;
async fn birth(
&self,
_parent: A,
child: Create<A, Never>,
_response: S,
) -> Result<Self::Lease, Self::Error> {
match child.child {}
}
}
#[allow(
private_bounds,
reason = "sealed birth-mode supertrait is deliberately crate-private"
)]
#[doc(hidden)]
pub trait RuntimeBirthMode<A: Address, Y, S>: BirthMode + SealedBirthMode {
type Runtime: ChildRuntime<A, Self::Child, S>;
fn runtime(system: Y) -> Self::Runtime;
}
impl<A, Y, S> RuntimeBirthMode<A, Y, S> for NoBirths
where
A: Address + Send,
A::Nonce: Send,
S: Send,
{
type Runtime = NoChildren;
fn runtime(_system: Y) -> Self::Runtime {
NoChildren::new()
}
}
#[doc(hidden)]
pub struct SystemChildren<Y> {
pub(crate) system: Y,
}
impl<Y> SealedChildRuntime for SystemChildren<Y> {}
impl<A: Address, Y, C, S> RuntimeBirthMode<A, Y, S> for Births<C>
where
SystemChildren<Y>: ChildRuntime<A, C, S>,
{
type Runtime = SystemChildren<Y>;
fn runtime(system: Y) -> Self::Runtime {
SystemChildren { system }
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[doc(hidden)]
pub enum RuntimeEffectError<C, D> {
#[error("child birth failed: {0:?}")]
Birth(C),
#[error("a behavior reused a child identity within one parent incarnation")]
DuplicateChild,
#[error("outbound delivery failed: {0:?}")]
Delivery(D),
}
pub trait CreationFailure {
fn rejection(&self) -> behavior::CreationRejection;
}
impl CreationFailure for Never {
fn rejection(&self) -> behavior::CreationRejection {
match *self {}
}
}