use crate::{ComposedEvent, Delivery, InjectEvent, Inside, Protocol};
use core::future::Future;
pub trait SendInterpreter: Send {
type Error;
}
pub trait InterpretSends<Interpreter: SendInterpreter, RootEvent, Path>: Sized + Send {
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send;
}
pub trait InterpretRequest<Request, RootEvent, Path>: SendInterpreter {
fn interpret_request(
&mut self,
request: Request,
) -> impl Future<Output = Result<(), Self::Error>> + Send;
}
pub trait InterpretDelivery<P: Protocol>: SendInterpreter {
fn interpret_delivery(
&mut self,
delivery: Delivery<P>,
) -> impl Future<Output = Result<(), Self::Error>> + Send;
}
pub enum Own {}
pub trait SendInput<Input, Path> {
fn emit(&mut self, input: Input);
}
pub trait SendEffects: Sized {
fn empty() -> Self;
fn append(&mut self, other: Self);
#[must_use]
fn combine(mut self, other: Self) -> Self {
self.append(other);
self
}
fn send<Input, Path>(&mut self, input: Input)
where
Self: SendInput<Input, Path>,
{
<Self as SendInput<Input, Path>>::emit(self, input);
}
#[must_use]
fn sending<Input, Path>(input: Input) -> Self
where
Self: SendInput<Input, Path>,
{
let mut sends = Self::empty();
sends.send(input);
sends
}
}
pub trait SendsFor<Event>: SendEffects {}
pub enum NoReturnToEmitter {}
pub struct ReturnsToEmitter<Input, Path>(core::marker::PhantomData<fn(Input, Path)>);
pub trait ReturnToEmitterFor<Event> {}
impl<Event> ReturnToEmitterFor<Event> for NoReturnToEmitter {}
impl<Event, Input, Path> ReturnToEmitterFor<Event> for ReturnsToEmitter<Input, Path> where
Event: InjectEvent<Input, Path>
{
}
pub trait InterpreterRequest {
type ReturnToEmitter;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoSends;
impl SendEffects for NoSends {
fn empty() -> Self {
Self
}
fn append(&mut self, _: Self) {}
}
impl<Event> SendsFor<Event> for NoSends {}
impl<Interpreter: SendInterpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path>
for NoSends
{
fn interpret(
self,
_: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send {
async { Ok(()) }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SendLayer<Owned, Inner> {
pub owned: Owned,
pub inner: Inner,
}
impl<Owned, Inner> SendLayer<Owned, Inner> {
#[must_use]
pub const fn new(owned: Owned, inner: Inner) -> Self {
Self { owned, inner }
}
}
impl<Owned: SendEffects, Inner: SendEffects> SendEffects for SendLayer<Owned, Inner> {
fn empty() -> Self {
Self::new(Owned::empty(), Inner::empty())
}
fn append(&mut self, other: Self) {
self.owned.append(other.owned);
self.inner.append(other.inner);
}
}
impl<Event, OwnedEffects, InnerEffects> SendsFor<Event> for SendLayer<OwnedEffects, InnerEffects>
where
Event: ComposedEvent,
OwnedEffects: SendsFor<Event>,
InnerEffects: SendsFor<Event::Inner>,
{
}
impl<Input, Path, Owned, Inner> SendInput<Input, Path> for SendLayer<Owned, Inner>
where
Owned: SendInput<Input, Path>,
{
fn emit(&mut self, input: Input) {
self.owned.emit(input);
}
}
impl<Interpreter, RootEvent, Path, Owned, Inner> InterpretSends<Interpreter, RootEvent, Path>
for SendLayer<Owned, Inner>
where
Interpreter: SendInterpreter,
Interpreter: Send,
Owned: InterpretSends<Interpreter, RootEvent, Path> + Send,
Inner: InterpretSends<Interpreter, RootEvent, Inside<Path>> + Send,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send {
async move {
<Inner as InterpretSends<Interpreter, RootEvent, Inside<Path>>>::interpret(
self.inner,
interpreter,
)
.await?;
<Owned as InterpretSends<Interpreter, RootEvent, Path>>::interpret(
self.owned,
interpreter,
)
.await
}
}
}
impl<T> SendEffects for Vec<T> {
fn empty() -> Self {
Vec::new()
}
fn append(&mut self, mut other: Self) {
Vec::append(self, &mut other);
}
}
impl<Event, T> SendsFor<Event> for Vec<T> {}
impl<Interpreter, RootEvent, Path, P> InterpretSends<Interpreter, RootEvent, Path>
for Vec<Delivery<P>>
where
Interpreter: InterpretDelivery<P>,
Interpreter: Send,
P: Protocol,
Delivery<P>: Send,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send {
async move {
for delivery in self {
interpreter.interpret_delivery(delivery).await?;
}
Ok(())
}
}
}
impl<Interpreter: SendInterpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path>
for Vec<crate::Never>
{
fn interpret(
self,
_: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send {
async move {
for never in self {
match never {}
}
Ok(())
}
}
}
impl<T> SendInput<T, Own> for Vec<T> {
fn emit(&mut self, input: T) {
self.push(input);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterpreterRequests<M> {
requests: Vec<M>,
}
impl<M> InterpreterRequests<M> {
#[must_use]
pub fn new(requests: Vec<M>) -> Self {
Self { requests }
}
#[must_use]
pub fn one(request: M) -> Self {
Self::new(vec![request])
}
#[must_use]
pub fn as_slice(&self) -> &[M] {
&self.requests
}
pub fn iter(&self) -> core::slice::Iter<'_, M> {
self.requests.iter()
}
#[must_use]
pub fn len(&self) -> usize {
self.requests.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.requests.is_empty()
}
pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
self.requests.extend(requests);
}
#[must_use]
pub fn into_requests(self) -> Vec<M> {
self.requests
}
}
impl<M> core::ops::Index<usize> for InterpreterRequests<M> {
type Output = M;
fn index(&self, index: usize) -> &Self::Output {
&self.requests[index]
}
}
impl<M> IntoIterator for InterpreterRequests<M> {
type Item = M;
type IntoIter = std::vec::IntoIter<M>;
fn into_iter(self) -> Self::IntoIter {
self.requests.into_iter()
}
}
impl<'a, M> IntoIterator for &'a InterpreterRequests<M> {
type Item = &'a M;
type IntoIter = core::slice::Iter<'a, M>;
fn into_iter(self) -> Self::IntoIter {
self.requests.iter()
}
}
impl<M> SendEffects for InterpreterRequests<M> {
fn empty() -> Self {
Self::new(Vec::new())
}
fn append(&mut self, mut other: Self) {
self.requests.append(&mut other.requests);
}
}
impl<Event, M> SendsFor<Event> for InterpreterRequests<M>
where
M: InterpreterRequest,
M::ReturnToEmitter: ReturnToEmitterFor<Event>,
{
}
impl<M> SendInput<M, Own> for InterpreterRequests<M> {
fn emit(&mut self, input: M) {
self.requests.push(input);
}
}
impl<Interpreter, RootEvent, Path, Request> InterpretSends<Interpreter, RootEvent, Path>
for InterpreterRequests<Request>
where
Interpreter: InterpretRequest<Request, RootEvent, Path>,
Interpreter: Send,
Request: Send,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Result<(), Interpreter::Error>> + Send {
async move {
for request in self {
<Interpreter as InterpretRequest<Request, RootEvent, Path>>::interpret_request(
interpreter,
request,
)
.await?;
}
Ok(())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn send_accumulation_obeys_identity_and_associativity() {
let values = vec![1, 2];
assert_eq!(Vec::new().combine(values.clone()), values);
assert_eq!(values.clone().combine(Vec::new()), values);
let left = vec![1].combine(vec![2]).combine(vec![3]);
let right = vec![1].combine(vec![2].combine(vec![3]));
assert_eq!(left, right);
}
#[test]
fn vector_and_service_lanes_emit_and_iterate_in_order() {
assert!(<Vec<u8> as SendEffects>::empty().is_empty());
let mut vector = Vec::new();
<Vec<u8> as SendInput<u8, Own>>::emit(&mut vector, 1);
assert_eq!(vector, [1]);
let mut services = InterpreterRequests::one(2);
services.extend([4, 5]);
<InterpreterRequests<u8> as SendInput<u8, Own>>::emit(&mut services, 3);
assert!(!services.is_empty());
assert_eq!(services.as_slice(), [2, 4, 5, 3]);
assert_eq!(
(&services).into_iter().copied().collect::<Vec<_>>(),
[2, 4, 5, 3]
);
assert_eq!(services.into_iter().collect::<Vec<_>>(), [2, 4, 5, 3]);
let requests = InterpreterRequests::new(vec![4, 5]).into_requests();
assert_eq!(requests, [4, 5]);
}
struct Returning;
impl InterpreterRequest for Returning {
type ReturnToEmitter = ReturnsToEmitter<u8, crate::Here>;
}
fn lawful<Event, Effects: SendsFor<Event>>() {}
#[test]
fn local_return_proofs_compose_through_exact_event_layers() {
type Inner = crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>;
type Outer = crate::EventLayer<(), Inner>;
lawful::<Inner, InterpreterRequests<Returning>>();
lawful::<Outer, SendLayer<NoSends, InterpreterRequests<Returning>>>();
}
#[test]
fn send_layer_emits_into_its_designated_owned_lane() {
let mut effects = SendLayer::new(Vec::<u8>::new(), Vec::<u16>::new());
<SendLayer<Vec<u8>, Vec<u16>> as SendInput<u8, Own>>::emit(&mut effects, 7);
assert_eq!(effects.owned, [7]);
assert!(effects.inner.is_empty());
}
#[derive(Debug, PartialEq, Eq)]
enum Seen {
Inner(u8),
Outer(u16),
}
struct Trace(Vec<Seen>);
type TraceEvent =
crate::EventLayer<u16, crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>>;
impl SendInterpreter for Trace {
type Error = core::convert::Infallible;
}
impl InterpretRequest<u8, TraceEvent, crate::Inside<crate::Here>> for Trace {
fn interpret_request(
&mut self,
request: u8,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
async move {
self.0.push(Seen::Inner(request));
Ok(())
}
}
}
impl InterpretRequest<u16, TraceEvent, crate::Here> for Trace {
fn interpret_request(
&mut self,
request: u16,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
async move {
self.0.push(Seen::Outer(request));
Ok(())
}
}
}
#[tokio::test]
async fn structural_interpretation_visits_every_lane_inner_to_outer() {
let effects = SendLayer::new(
InterpreterRequests::new(vec![3_u16, 5]),
SendLayer::new(InterpreterRequests::one(2_u8), NoSends),
);
let mut trace = Trace(Vec::new());
<_ as InterpretSends<_, TraceEvent, crate::Here>>::interpret(effects, &mut trace)
.await
.unwrap();
assert_eq!(trace.0, [Seen::Inner(2), Seen::Outer(3), Seen::Outer(5)]);
}
}