1use actix_web::web::Bytes;
2use bytestring::ByteString;
3use serde::{de::DeserializeOwned, Serialize};
4
5use super::{CodecMessage, EncodedMessage, MessageCodec};
6use crate::AggregatedMessage;
7
8#[derive(Debug, Clone, Copy, Default)]
12pub struct JsonCodec {
13 send_mode: JsonSendMode,
14}
15
16#[derive(Debug, Clone, Copy, Default)]
17enum JsonSendMode {
18 #[default]
19 Text,
20 Binary,
21}
22
23impl JsonCodec {
24 #[must_use]
26 pub fn new() -> Self {
27 Self::default()
28 }
29
30 #[must_use]
32 pub fn text(mut self) -> Self {
33 self.send_mode = JsonSendMode::Text;
34 self
35 }
36
37 #[must_use]
41 pub fn binary(mut self) -> Self {
42 self.send_mode = JsonSendMode::Binary;
43 self
44 }
45}
46
47impl<T> MessageCodec<T> for JsonCodec
48where
49 T: Serialize + DeserializeOwned,
50{
51 type Error = serde_json::Error;
52
53 fn encode(&self, item: &T) -> Result<EncodedMessage, Self::Error> {
54 match self.send_mode {
55 JsonSendMode::Text => {
56 let json = serde_json::to_string(item)?;
57 Ok(EncodedMessage::Text(ByteString::from(json)))
58 }
59 JsonSendMode::Binary => {
60 let json = serde_json::to_vec(item)?;
61 Ok(EncodedMessage::Binary(Bytes::from(json)))
62 }
63 }
64 }
65
66 fn decode(&self, msg: AggregatedMessage) -> Result<CodecMessage<T>, Self::Error> {
67 match msg {
68 AggregatedMessage::Text(text) => {
69 serde_json::from_str(text.as_ref()).map(CodecMessage::Item)
70 }
71 AggregatedMessage::Binary(bin) => serde_json::from_slice(&bin).map(CodecMessage::Item),
72 AggregatedMessage::Ping(bytes) => Ok(CodecMessage::Ping(bytes)),
73 AggregatedMessage::Pong(bytes) => Ok(CodecMessage::Pong(bytes)),
74 AggregatedMessage::Close(reason) => Ok(CodecMessage::Close(reason)),
75 }
76 }
77}