use crate::core::io::BroadcastScope;
use crate::core::utils::Sealed;
use crate::protocol::{DialectSpec, FrameProcessor};
use crate::prelude::*;
pub trait SendFrameInternal<V: MaybeVersioned>: Sealed {
fn processor_internal(&self) -> &FrameProcessor;
unsafe fn route_frame_internal(&self, frame: Frame<V>, scope: BroadcastScope) -> Result<()>;
}
pub trait SendMessageInternal<V: MaybeVersioned>: Sealed {
fn endpoint(&self) -> &Endpoint<V>;
}
pub trait SendFrame<V: MaybeVersioned>: SendFrameInternal<V> {
#[inline]
fn dialect(&self) -> &DialectSpec {
self.processor_internal().main_dialect()
}
#[inline(always)]
fn known_dialects(&self) -> impl Iterator<Item = &DialectSpec> {
self.processor_internal().known_dialects()
}
fn send_frame(&self, frame: &Frame<V>) -> Result<()> {
let mut frame = frame.clone();
self.processor_internal().process_outgoing(&mut frame)?;
unsafe { self.route_frame_internal(frame, BroadcastScope::All) }
}
fn broadcast_frame(&self, frame: &Frame<V>, scope: BroadcastScope) -> Result<()> {
let mut frame = frame.clone();
self.processor_internal().process_outgoing(&mut frame)?;
unsafe { self.route_frame_internal(frame, scope) }
}
}
pub trait SendMessage<V: Versioned>: SendFrame<V> + SendMessageInternal<V> {
fn send(&self, message: &impl Message) -> Result<()> {
let frame = self.next_frame(message)?;
self.send_frame(&frame)
}
fn broadcast(&self, message: &impl Message, scope: BroadcastScope) -> Result<()> {
let frame = self.next_frame(message)?;
self.broadcast_frame(&frame, scope)
}
fn next_frame(&self, message: &impl Message) -> Result<Frame<V>> {
let mut frame = self.endpoint().next_frame(message)?;
self.processor_internal().process_new(&mut frame);
Ok(frame)
}
}
pub trait SendVersionlessMessage:
SendFrame<Versionless> + SendMessageInternal<Versionless>
{
fn send_versioned<V: Versioned>(&self, message: &impl Message) -> Result<()> {
let frame = self.next_frame_versioned::<V>(message)?;
self.send_frame(&frame)
}
fn broadcast_versioned<V: Versioned>(
&self,
message: &impl Message,
scope: BroadcastScope,
) -> Result<()> {
let frame = self.next_frame_versioned::<V>(message)?;
self.broadcast_frame(&frame, scope)
}
fn next_frame_versioned<V: Versioned>(
&self,
message: &impl Message,
) -> Result<Frame<Versionless>> {
let mut frame = self.endpoint().next_frame::<V>(message)?;
self.processor_internal().process_new(&mut frame);
Ok(frame)
}
}