nautilus_core/
serialization.rs1use bytes::Bytes;
19use serde::{
20 Deserializer,
21 de::{Unexpected, Visitor},
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 to_json_bytes(&self) -> Result<Bytes, serde_json::Error> {
53 serde_json::to_vec(self).map(Bytes::from)
54 }
55
56 fn to_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 #[allow(clippy::cast_possible_truncation)]
81 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
82 where
83 E: serde::de::Error,
84 {
85 if value > 1 {
90 Err(E::invalid_value(Unexpected::Unsigned(value), &self))
91 } else {
92 Ok(value as u8)
93 }
94 }
95}
96
97pub fn from_bool_as_u8<'de, D>(deserializer: D) -> Result<u8, D::Error>
103where
104 D: Deserializer<'de>,
105{
106 deserializer.deserialize_any(BoolVisitor)
107}
108
109#[cfg(test)]
113mod tests {
114 use rstest::*;
115 use serde::Deserialize;
116
117 use super::from_bool_as_u8;
118
119 #[derive(Deserialize)]
120 pub struct TestStruct {
121 #[serde(deserialize_with = "from_bool_as_u8")]
122 pub value: u8,
123 }
124
125 #[rstest]
126 #[case(r#"{"value": true}"#, 1)]
127 #[case(r#"{"value": false}"#, 0)]
128 fn test_deserialize_bool_as_u8_with_boolean(#[case] json_str: &str, #[case] expected: u8) {
129 let test_struct: TestStruct = serde_json::from_str(json_str).unwrap();
130 assert_eq!(test_struct.value, expected);
131 }
132
133 #[rstest]
134 #[case(r#"{"value": 1}"#, 1)]
135 #[case(r#"{"value": 0}"#, 0)]
136 fn test_deserialize_bool_as_u8_with_u64(#[case] json_str: &str, #[case] expected: u8) {
137 let test_struct: TestStruct = serde_json::from_str(json_str).unwrap();
138 assert_eq!(test_struct.value, expected);
139 }
140
141 #[rstest]
142 fn test_deserialize_bool_as_u8_with_invalid_integer() {
143 let json = r#"{"value": 2}"#;
145 let result: Result<TestStruct, _> = serde_json::from_str(json);
146 assert!(result.is_err());
147 }
148}