Skip to main content

capp_queue/
serializers.rs

1use super::{Task, TaskQueueError};
2use serde::{Serialize, de::DeserializeOwned};
3
4// Marker traits for backend compatibility
5pub trait InMemoryCompatible {}
6
7// Mark which backends JsonSerializer is compatible with
8impl InMemoryCompatible for JsonSerializer {}
9
10pub trait TaskSerializer: Send + Sync {
11    fn serialize_task<T>(task: &Task<T>) -> Result<Vec<u8>, TaskQueueError>
12    where
13        T: Clone + Serialize + DeserializeOwned;
14
15    fn deserialize_task<T>(data: &[u8]) -> Result<Task<T>, TaskQueueError>
16    where
17        T: Clone + Serialize + DeserializeOwned;
18}
19
20#[derive(Debug, Clone, Copy)]
21pub struct JsonSerializer;
22
23impl TaskSerializer for JsonSerializer {
24    fn serialize_task<T>(task: &Task<T>) -> Result<Vec<u8>, TaskQueueError>
25    where
26        T: Serialize + DeserializeOwned + Clone,
27    {
28        serde_json::to_vec(task)
29            .map_err(|e| TaskQueueError::Serialization(e.to_string()))
30    }
31
32    fn deserialize_task<T>(data: &[u8]) -> Result<Task<T>, TaskQueueError>
33    where
34        T: Serialize + DeserializeOwned + Clone,
35    {
36        serde_json::from_slice(data)
37            .map_err(|e| TaskQueueError::Deserialization(e.to_string()))
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::{JsonSerializer, TaskSerializer};
44    use crate::{Task, TaskQueueError};
45    use serde::{Deserialize, Serialize, Serializer};
46
47    #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
48    struct Payload {
49        value: u32,
50    }
51
52    #[derive(Clone, Debug, Deserialize)]
53    struct FailingPayload;
54
55    impl Serialize for FailingPayload {
56        fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
57        where
58            S: Serializer,
59        {
60            Err(serde::ser::Error::custom("boom"))
61        }
62    }
63
64    #[test]
65    fn json_serializer_round_trips_task() {
66        let task = Task::new(Payload { value: 42 });
67        let encoded = JsonSerializer::serialize_task(&task).unwrap();
68        let decoded =
69            JsonSerializer::deserialize_task::<Payload>(&encoded).unwrap();
70
71        assert_eq!(decoded.payload, task.payload);
72        assert_eq!(decoded.status, task.status);
73    }
74
75    #[test]
76    fn json_serializer_reports_serialization_errors() {
77        let task = Task::new(FailingPayload);
78        let error = JsonSerializer::serialize_task(&task).unwrap_err();
79
80        match error {
81            TaskQueueError::Serialization(msg) => assert!(msg.contains("boom")),
82            other => panic!("unexpected error: {other:?}"),
83        }
84    }
85
86    #[test]
87    fn json_serializer_reports_deserialization_errors() {
88        let error = JsonSerializer::deserialize_task::<Payload>(b"not valid json")
89            .unwrap_err();
90
91        match error {
92            TaskQueueError::Deserialization(_) => {}
93            other => panic!("unexpected error: {other:?}"),
94        }
95    }
96}