capp_queue/
serializers.rs1use super::{Task, TaskQueueError};
2use serde::{Serialize, de::DeserializeOwned};
3
4pub trait InMemoryCompatible {}
6
7impl 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}