null_terminated_str/
serde_impl.rs1use std::ops::Deref;
2
3use serde::{
4 de::{Deserialize, Deserializer, Error, Unexpected},
5 Serialize, Serializer,
6};
7
8use super::{NullTerminatedStr, NullTerminatedString};
9
10impl Serialize for NullTerminatedStr {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: Serializer,
14 {
15 serializer.serialize_bytes(self.as_c_str().to_bytes_with_nul())
16 }
17}
18
19impl Serialize for NullTerminatedString {
20 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21 where
22 S: Serializer,
23 {
24 self.deref().serialize(serializer)
25 }
26}
27
28impl<'de: 'a, 'a> Deserialize<'de> for &'a NullTerminatedStr {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'de>,
32 {
33 let s = <&str>::deserialize(deserializer)?;
34 NullTerminatedStr::try_from_str(s).ok_or_else(|| {
35 D::Error::invalid_value(Unexpected::Str(s), &"Expected null terminated utf-8 str")
36 })
37 }
38}
39
40impl<'de> Deserialize<'de> for NullTerminatedString {
41 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42 where
43 D: Deserializer<'de>,
44 {
45 let s = <String>::deserialize(deserializer)?;
46 Ok(NullTerminatedString::from(s))
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use crate::{const_null_terminated_str, NullTerminatedStr, NullTerminatedString};
53 use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
54
55 #[test]
56 fn test_de_ser_null_terminated_str() {
57 macro_rules! def_str_test {
58 ($s:expr) => {
59 assert_tokens(
60 &const_null_terminated_str!($s),
61 &[Token::BorrowedBytes(concat!($s, "\0").as_bytes())],
62 );
63
64 assert_tokens(
65 &(const_null_terminated_str!($s)).to_owned(),
66 &[Token::BorrowedBytes(concat!($s, "\0").as_bytes())],
67 );
68 };
69 }
70
71 def_str_test!("");
72 def_str_test!("abcde");
73 }
74
75 #[test]
76 fn test_de_ser_null_terminated_str_err() {
77 let strs: &[&str] = &["", "abcde"];
78
79 for s in strs {
80 let byte = s.as_bytes();
81 assert_de_tokens_error::<&NullTerminatedStr>(
82 &[Token::BorrowedBytes(byte)],
83 &format!(
84 r#"invalid value: string "{}", expected Expected null terminated utf-8 str"#,
85 s
86 ),
87 );
88
89 assert_de_tokens::<NullTerminatedString>(
90 &NullTerminatedString::from(*s),
91 &[Token::BorrowedBytes(byte)],
92 );
93 }
94 }
95}