1use serde::{de::DeserializeOwned, Serialize};
12
13use crate::error::Result;
14
15pub trait CodecType: Clone + Send + Sync + 'static {
20 fn encode<T: Serialize>(value: &T) -> Result<Vec<u8>>;
22
23 fn decode<T: DeserializeOwned>(data: &[u8]) -> Result<T>;
25}
26
27#[cfg(feature = "msgpack")]
42#[derive(Debug, Clone, Copy, Default)]
43pub struct MsgPackCodec;
44
45#[cfg(feature = "msgpack")]
46impl CodecType for MsgPackCodec {
47 fn encode<T: Serialize>(value: &T) -> Result<Vec<u8>> {
48 Ok(rmp_serde::to_vec(value)?)
49 }
50
51 fn decode<T: DeserializeOwned>(data: &[u8]) -> Result<T> {
52 Ok(rmp_serde::from_slice(data)?)
53 }
54}
55
56#[cfg(feature = "json")]
71#[derive(Debug, Clone, Copy, Default)]
72pub struct JsonCodec;
73
74#[cfg(feature = "json")]
75impl CodecType for JsonCodec {
76 fn encode<T: Serialize>(value: &T) -> Result<Vec<u8>> {
77 Ok(serde_json::to_vec(value)?)
78 }
79
80 fn decode<T: DeserializeOwned>(data: &[u8]) -> Result<T> {
81 Ok(serde_json::from_slice(data)?)
82 }
83}
84
85pub trait Encode {
87 fn encode(&self) -> Result<Vec<u8>>;
89}
90
91pub trait Decode: Sized {
93 fn decode(data: &[u8]) -> Result<Self>;
95}
96
97pub trait Codec: Encode + Decode {}
99
100#[cfg(feature = "msgpack")]
102pub type DefaultCodec = MsgPackCodec;
104
105#[cfg(all(feature = "json", not(feature = "msgpack")))]
106pub type DefaultCodec = JsonCodec;
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use serde::{Deserialize, Serialize};
113
114 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
115 struct TestMessage {
116 id: u64,
117 content: String,
118 }
119
120 #[cfg(feature = "msgpack")]
121 #[test]
122 fn test_msgpack_encode_decode_roundtrip() {
123 let msg = TestMessage {
124 id: 42,
125 content: "hello world".to_string(),
126 };
127
128 let encoded = MsgPackCodec::encode(&msg).unwrap();
129 let decoded: TestMessage = MsgPackCodec::decode(&encoded).unwrap();
130
131 assert_eq!(msg, decoded);
132 }
133
134 #[cfg(feature = "msgpack")]
135 #[test]
136 fn test_msgpack_is_compact() {
137 let msg = TestMessage {
138 id: 1,
139 content: "test".to_string(),
140 };
141
142 let encoded = MsgPackCodec::encode(&msg).unwrap();
143 assert!(!encoded.is_empty());
145 let json = serde_json::to_vec(&msg).unwrap();
147 assert!(encoded.len() <= json.len());
148 }
149
150 #[cfg(feature = "json")]
151 #[test]
152 fn test_json_encode_decode_roundtrip() {
153 let msg = TestMessage {
154 id: 42,
155 content: "hello world".to_string(),
156 };
157
158 let encoded = JsonCodec::encode(&msg).unwrap();
159 let decoded: TestMessage = JsonCodec::decode(&encoded).unwrap();
160
161 assert_eq!(msg, decoded);
162 }
163
164 #[cfg(feature = "json")]
165 #[test]
166 fn test_json_is_readable() {
167 let msg = TestMessage {
168 id: 1,
169 content: "test".to_string(),
170 };
171
172 let encoded = JsonCodec::encode(&msg).unwrap();
173 let json_str = std::str::from_utf8(&encoded).unwrap();
175 assert!(json_str.contains("\"id\":1"));
176 assert!(json_str.contains("\"content\":\"test\""));
177 }
178}