1use std::marker::PhantomData;
2
3use apalis_core::backend::codec::Codec;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7#[derive(Debug, Clone, Default)]
9pub struct JsonCodec<Output = Vec<u8>> {
10 _o: PhantomData<Output>,
11}
12
13impl<T: Serialize + for<'de> Deserialize<'de>> Codec<T> for JsonCodec<Vec<u8>> {
14 type Compact = Vec<u8>;
15 type Error = serde_json::Error;
16 fn encode(&self, input: &T) -> Result<Vec<u8>, Self::Error> {
17 serde_json::to_vec(input)
18 }
19
20 fn decode(&self, compact: &Vec<u8>) -> Result<T, Self::Error> {
21 serde_json::from_slice(compact)
22 }
23}
24
25impl<T: Serialize + for<'de> Deserialize<'de>> Codec<T> for JsonCodec<String> {
26 type Compact = String;
27 type Error = serde_json::Error;
28 fn encode(&self, input: &T) -> Result<String, Self::Error> {
29 serde_json::to_string(input)
30 }
31 fn decode(&self, compact: &String) -> Result<T, Self::Error> {
32 serde_json::from_str(compact)
33 }
34}
35
36impl<T: Serialize + for<'de> Deserialize<'de>> Codec<T> for JsonCodec<Value> {
37 type Compact = Value;
38 type Error = serde_json::Error;
39 fn encode(&self, input: &T) -> Result<Value, Self::Error> {
40 serde_json::to_value(input)
41 }
42
43 fn decode(&self, compact: &Value) -> Result<T, Self::Error> {
44 T::deserialize(compact)
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[derive(Serialize, Deserialize, Debug, PartialEq)]
53 struct TestStruct {
54 id: u32,
55 name: String,
56 }
57
58 #[test]
59 fn test_json_codec_vec_u8_roundtrip() {
60 let original = TestStruct {
61 id: 1,
62 name: "Test".to_string(),
63 };
64 let codec = JsonCodec::<Vec<u8>>::default();
65 let encoded = codec.encode(&original).unwrap();
66 let decoded: TestStruct = codec.decode(&encoded).unwrap();
67 assert_eq!(original, decoded);
68 }
69
70 #[test]
71 fn test_json_codec_string_roundtrip() {
72 let original = TestStruct {
73 id: 2,
74 name: "Example".to_string(),
75 };
76 let codec = JsonCodec::<String>::default();
77 let encoded = codec.encode(&original).unwrap();
78 let decoded: TestStruct = codec.decode(&encoded).unwrap();
79 assert_eq!(original, decoded);
80 }
81
82 #[test]
83 fn test_json_codec_value_roundtrip() {
84 let original = TestStruct {
85 id: 3,
86 name: "Sample".to_string(),
87 };
88 let codec = JsonCodec::<Value>::default();
89 let encoded = codec.encode(&original).unwrap();
90 let decoded: TestStruct = codec.decode(&encoded).unwrap();
91 assert_eq!(original, decoded);
92 }
93}