use std::borrow::Cow;
use crate::Publisher;
use crate::runtime::publish::{
DestinationUse, Either, FitsTaken, ForReply, Names, PublishTransform, PublishTransformIdentity,
PublishTransformStack, Reads,
};
use super::StepOpen;
use crate::{AddressedCopies, BrokerMoves, NamedCopies};
#[doc(hidden)]
#[derive(Debug, Clone, Copy, Default)]
pub struct OpenDestination;
#[doc(hidden)]
#[derive(Debug, Clone, Copy, Default)]
pub struct FixedDestination;
#[doc(hidden)]
pub trait RetryOffer<Dest> {
type Offer: DestinationUse;
}
macro_rules! impl_declared_offer {
($($path:ident),+ $(,)?) => {$(
impl<Dest> RetryOffer<Dest> for $path {
type Offer = Reads;
}
)+};
}
impl_declared_offer!(AddressedCopies, BrokerMoves);
impl RetryOffer<OpenDestination> for NamedCopies {
type Offer = Names;
}
impl RetryOffer<FixedDestination> for NamedCopies {
type Offer = Reads;
}
#[doc(hidden)]
pub trait RetryStackUse<Live, Cx> {
type Destination: DestinationUse;
}
impl<Live, Cx> RetryStackUse<Live, Cx> for PublishTransformIdentity {
type Destination = Reads;
}
impl<Live: Publisher, Cx, Inner, Outer> RetryStackUse<Live, Cx>
for PublishTransformStack<Inner, Outer>
where
Inner: RetryStackUse<Live, Cx>,
Outer: PublishTransform<ForReply<Cx>, Live::Options>,
Outer::Destination: FitsTaken<Inner::Destination> + Either<Inner::Destination>,
<Outer::Destination as Either<Inner::Destination>>::Out: DestinationUse,
{
type Destination = <Outer::Destination as Either<Inner::Destination>>::Out;
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, Default)]
pub struct DestinationDeclared;
#[doc(hidden)]
#[derive(Debug, Clone, Copy, Default)]
pub struct DestinationUndeclared;
#[doc(hidden)]
pub trait SettlesDestination<Stack> {
type Settled;
}
impl<Stack> SettlesDestination<Stack> for Reads {
type Settled = DestinationDeclared;
}
impl SettlesDestination<Self> for Names {
type Settled = DestinationDeclared;
}
impl SettlesDestination<Reads> for Names {
type Settled = DestinationUndeclared;
}
#[doc(hidden)]
#[diagnostic::on_unimplemented(
message = "`.to(..)` has no destination to name here",
label = "`{Self}`: the destination was named already, or this position takes none",
note = "`.to(name)` names where a registration's retry copies go, once, right after \
`out_retry(policy)`; a reply's destination comes from its own type or from the mount \
site's `reply(\"dest\")`, and an `Out` slot's from the type it publishes"
)]
pub trait DestinationOpen {}
impl DestinationOpen for StepOpen {}
#[doc(hidden)]
pub trait DestinationLast<Index> {
type Step;
type Out;
fn destination_last(self, destination: Cow<'static, str>) -> Self::Out;
}