nautilus_core/
serialization.rs1use bytes::Bytes;
19use serde::{
20 de::{Unexpected, Visitor},
21 Deserializer,
22};
23
24struct BoolVisitor;
25use serde::{Deserialize, Serialize};
26
27pub trait Serializable: Serialize + for<'de> Deserialize<'de> {
29 fn from_json_bytes(data: &[u8]) -> Result<Self, serde_json::Error> {
35 serde_json::from_slice(data)
36 }
37
38 fn from_msgpack_bytes(data: &[u8]) -> Result<Self, rmp_serde::decode::Error> {
44 rmp_serde::from_slice(data)
45 }
46
47 fn as_json_bytes(&self) -> Result<Bytes, serde_json::Error> {
53 serde_json::to_vec(self).map(Bytes::from)
54 }
55
56 fn as_msgpack_bytes(&self) -> Result<Bytes, rmp_serde::encode::Error> {
62 rmp_serde::to_vec_named(self).map(Bytes::from)
63 }
64}
65
66impl Visitor<'_> for BoolVisitor {
67 type Value = u8;
68
69 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 formatter.write_str("a boolean as u8")
71 }
72
73 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
74 where
75 E: serde::de::Error,
76 {
77 Ok(u8::from(value))
78 }
79
80 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
81 where
82 E: serde::de::Error,
83 {
84 if value > u64::from(u8::MAX) {
85 Err(E::invalid_value(Unexpected::Unsigned(value), &self))
86 } else {
87 Ok(value as u8)
88 }
89 }
90}
91
92pub fn from_bool_as_u8<'de, D>(deserializer: D) -> Result<u8, D::Error>
98where
99 D: Deserializer<'de>,
100{
101 deserializer.deserialize_any(BoolVisitor)
102}
103
104#[cfg(test)]
108mod tests {
109 use rstest::*;
110 use serde::Deserialize;
111
112 use super::from_bool_as_u8;
113
114 #[derive(Deserialize)]
115 pub struct TestStruct {
116 #[serde(deserialize_with = "from_bool_as_u8")]
117 pub value: u8,
118 }
119
120 #[rstest]
121 #[case(r#"{"value": true}"#, 1)]
122 #[case(r#"{"value": false}"#, 0)]
123 fn test_deserialize_bool_as_u8_with_boolean(#[case] json_str: &str, #[case] expected: u8) {
124 let test_struct: TestStruct = serde_json::from_str(json_str).unwrap();
125 assert_eq!(test_struct.value, expected);
126 }
127
128 #[rstest]
129 #[case(r#"{"value": 1}"#, 1)]
130 #[case(r#"{"value": 0}"#, 0)]
131 fn test_deserialize_bool_as_u8_with_u64(#[case] json_str: &str, #[case] expected: u8) {
132 let test_struct: TestStruct = serde_json::from_str(json_str).unwrap();
133 assert_eq!(test_struct.value, expected);
134 }
135}