reach_websocket/
context.rs

1// SPDX-FileCopyrightText: 2025 Michael Goldenberg <m@mgoldenberg.net>
2// SPDX-License-Identifier: EUPL-1.2
3
4use futures::Stream;
5
6use reach_core::{
7    communication::{CommunicableType, Communication},
8    error::GenericWebSocketError,
9};
10
11use super::WebSocketError;
12use crate::{WebSocketItem, WebSocketStreamResult};
13
14#[derive(Debug)]
15pub enum Next<Incoming, Outgoing, Responder> {
16    Incoming(Communication<Incoming>),
17    Outgoing(WebSocketItem<Communication<Outgoing>, Responder>),
18}
19
20pub type NextOutput<I, O, R> = Option<WebSocketStreamResult<Next<I, O, R>>>;
21
22pub trait WebSocketContext:
23    Stream<Item = WebSocketStreamResult<Next<Self::Incoming, Self::Outgoing, Self::Responder>>>
24    + WebSocketErrorResponder
25    + Sized
26{
27    type Options: IntoWebSocketContext<Self>;
28
29    type Incoming: CommunicableType;
30    type Outgoing: CommunicableType + From<GenericWebSocketError>;
31    type Responder;
32
33    fn with_options(
34        options: Self::Options,
35        channel: <Self::Options as IntoWebSocketContext<Self>>::Channel,
36    ) -> Self {
37        options.into_web_socket_context(channel)
38    }
39
40    fn handle_incoming(
41        &mut self,
42        incoming: Communication<Self::Incoming>,
43    ) -> impl Future<Output = Result<(), WebSocketError>> + Send;
44
45    fn handle_outgoing(
46        &mut self,
47        outgoing: WebSocketItem<Communication<Self::Outgoing>, Self::Responder>,
48    ) -> impl Future<Output = Result<(), WebSocketError>> + Send;
49}
50
51pub trait IntoWebSocketContext<C>
52where
53    C: WebSocketContext + Sized,
54{
55    type Channel;
56
57    fn into_web_socket_context(self, channel: Self::Channel) -> C;
58}
59
60pub trait WebSocketErrorResponder {
61    fn respond_with_error(
62        &mut self,
63        error: GenericWebSocketError,
64    ) -> impl Future<Output = WebSocketStreamResult<()>> + Send;
65}