Skip to main content

o_sfu_protocol/signaling/
codec.rs

1use super::{
2    ClientMessage, ClientRequest, ClientResponse, Envelope, EnvelopeDecodeError, RequestId,
3    ServerMessage, ServerRequest, ServerResponse, envelope::EnvelopeRoute,
4};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ClientEnvelope {
8    Message(ClientMessage),
9    Request {
10        request_id: RequestId,
11        request: ClientRequest,
12    },
13    Response {
14        response_to: RequestId,
15        response: ClientResponse,
16    },
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum ServerEnvelope {
21    Message(ServerMessage),
22    Request {
23        request_id: RequestId,
24        request: ServerRequest,
25    },
26    Response {
27        response_to: RequestId,
28        response: ServerResponse,
29    },
30}
31
32impl ClientEnvelope {
33    /// encode one typed client-side envelope into the websocket wire shape
34    ///
35    /// # Errors
36    ///
37    /// returns an error when the typed payload cannot be serialized into the
38    /// JSON envelope payload
39    pub fn into_envelope(self) -> Result<Envelope, serde_json::Error> {
40        match self {
41            Self::Message(message) => message.into_envelope(),
42            Self::Request {
43                request_id,
44                request,
45            } => request.into_envelope(request_id),
46            Self::Response {
47                response_to,
48                response,
49            } => response.into_envelope(response_to),
50        }
51    }
52
53    /// decode a raw websocket envelope into the typed native client contract
54    ///
55    /// # Errors
56    ///
57    /// returns an error when the tag is unknown or the payload does not match
58    /// the declared message shape
59    pub fn decode(envelope: Envelope) -> Result<Self, EnvelopeDecodeError> {
60        let (tag, payload, route) = envelope.into_parts();
61        match route {
62            EnvelopeRoute::Message => {
63                ClientMessage::decode(&tag, payload).map(ClientEnvelope::Message)
64            }
65            EnvelopeRoute::Request(request_id) => {
66                ClientRequest::decode(&tag, payload).map(|request| Self::Request {
67                    request_id,
68                    request,
69                })
70            }
71            EnvelopeRoute::Response(response_to) => {
72                ClientResponse::decode(&tag, payload).map(|response| Self::Response {
73                    response_to,
74                    response,
75                })
76            }
77        }
78    }
79}
80
81impl ServerEnvelope {
82    /// encode one typed server-side envelope into the websocket wire shape
83    ///
84    /// # Errors
85    ///
86    /// returns an error when the typed payload cannot be serialized into the
87    /// JSON envelope payload
88    pub fn into_envelope(self) -> Result<Envelope, serde_json::Error> {
89        match self {
90            Self::Message(message) => message.into_envelope(),
91            Self::Request {
92                request_id,
93                request,
94            } => request.into_envelope(request_id),
95            Self::Response {
96                response_to,
97                response,
98            } => response.into_envelope(response_to),
99        }
100    }
101
102    /// decode a raw websocket envelope into the typed native server contract
103    ///
104    /// # Errors
105    ///
106    /// returns an error when the tag is unknown or the payload does not match
107    /// the declared message shape
108    pub fn decode(envelope: Envelope) -> Result<Self, EnvelopeDecodeError> {
109        let (tag, payload, route) = envelope.into_parts();
110        match route {
111            EnvelopeRoute::Message => {
112                ServerMessage::decode(&tag, payload).map(ServerEnvelope::Message)
113            }
114            EnvelopeRoute::Request(request_id) => {
115                ServerRequest::decode(&tag, payload).map(|request| Self::Request {
116                    request_id,
117                    request,
118                })
119            }
120            EnvelopeRoute::Response(response_to) => {
121                ServerResponse::decode(&tag, payload).map(|response| Self::Response {
122                    response_to,
123                    response,
124                })
125            }
126        }
127    }
128}