dapi_grpc/mock/
serde_mockable.rs

1//! Serde serialization and deserialization for Mockable objects.
2//!
3//! This module provides a custom serialization and deserialization implementation for Mockable objects.
4//!
5//! /// ## Example
6///
7/// ```rust
8/// struct SomeObject {
9///    field: u32,
10/// }
11///
12/// impl dapi_grpc::mock::Mockable for SomeObject {
13///   fn mock_serialize(&self) -> Option<Vec<u8>> {
14///       Some(self.field.to_be_bytes().to_vec())
15///   }
16///
17///   fn mock_deserialize(bytes: &[u8]) -> Option<Self> {
18///      if bytes.len() != 4 {
19///         return None;
20///      }
21///
22///      Some(SomeObject {
23///         field: u32::from_be_bytes(bytes.try_into().expect("4 bytes")),
24///      })
25///   }
26/// }
27///
28/// #[derive(serde::Serialize,serde::Deserialize)]
29/// struct TestStruct {
30///     #[serde(with="dapi_grpc::mock::serde_mockable")]
31///     field: SomeObject,
32/// }
33/// ```
34use super::Mockable;
35
36use serde::{
37    de::{self, Visitor},
38    Deserializer, Serializer,
39};
40use serde_bytes::Deserialize;
41use std::fmt;
42use std::marker::PhantomData;
43
44/// Serialize any Mockable object to bytes.
45///
46/// ## Example
47///
48/// `#[serde(with="dapi_grpc::mock::serde_mockable")]`
49pub fn serialize<T: Mockable, S>(data: &T, serializer: S) -> Result<S::Ok, S::Error>
50where
51    S: Serializer,
52{
53    match data.mock_serialize() {
54        Some(bytes) => serializer.serialize_bytes(bytes.as_slice()),
55        None => Err(serde::ser::Error::custom(
56            "Mockable object is not serializable",
57        )),
58    }
59}
60
61struct MockableVisitor<T> {
62    marker: PhantomData<T>,
63}
64
65impl<'de, T> Visitor<'de> for MockableVisitor<T>
66where
67    T: Mockable,
68{
69    type Value = T;
70
71    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
72        formatter.write_str("a byte array")
73    }
74
75    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
76    where
77        E: de::Error,
78    {
79        T::mock_deserialize(v).ok_or_else(|| E::custom("Failed to deserialize Mockable object"))
80    }
81
82    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
83    where
84        A: de::SeqAccess<'de>,
85    {
86        let bytes = <Vec<u8>>::deserialize(de::value::SeqAccessDeserializer::new(seq))?;
87        T::mock_deserialize(&bytes).ok_or_else(|| {
88            serde::de::Error::custom("Failed to deserialize Mockable object from seq")
89        })
90    }
91}
92
93/// Deserialize any Mockable object from bytes.
94///
95/// ## Example
96///
97/// `#[serde(with="dapi_grpc::mock::serde_mockable")]`
98pub fn deserialize<'de, T: Mockable, D>(deserializer: D) -> Result<T, D::Error>
99where
100    D: Deserializer<'de>,
101{
102    deserializer.deserialize_bytes(MockableVisitor {
103        marker: PhantomData,
104    })
105}