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> {
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(input: &T) -> Result<Vec<u8>, Self::Error> {
17 serde_json::to_vec(input)
18 }
19
20 fn decode(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(input: &T) -> Result<String, Self::Error> {
29 serde_json::to_string(input)
30 }
31 fn decode(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(input: &T) -> Result<Value, Self::Error> {
40 serde_json::to_value(input)
41 }
42
43 fn decode(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 encoded = JsonCodec::<Vec<u8>>::encode(&original).unwrap();
65 let decoded: TestStruct = JsonCodec::<Vec<u8>>::decode(&encoded).unwrap();
66 assert_eq!(original, decoded);
67 }
68
69 #[test]
70 fn test_json_codec_string_roundtrip() {
71 let original = TestStruct {
72 id: 2,
73 name: "Example".to_string(),
74 };
75 let encoded = JsonCodec::<String>::encode(&original).unwrap();
76 let decoded: TestStruct = JsonCodec::<String>::decode(&encoded).unwrap();
77 assert_eq!(original, decoded);
78 }
79
80 #[test]
81 fn test_json_codec_value_roundtrip() {
82 let original = TestStruct {
83 id: 3,
84 name: "Sample".to_string(),
85 };
86 let encoded = JsonCodec::<Value>::encode(&original).unwrap();
87 let decoded: TestStruct = JsonCodec::<Value>::decode(&encoded).unwrap();
88 assert_eq!(original, decoded);
89 }
90}