non_empty_string/
serde_support.rs1use std::fmt;
2
3use serde::{
4 de::{self, Unexpected, Visitor},
5 ser::Serialize,
6};
7
8use crate::NonEmptyString;
9
10impl Serialize for NonEmptyString {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: serde::Serializer,
14 {
15 serializer.serialize_str(self.get())
16 }
17}
18
19struct NonEmptyStringVisitor;
20
21impl<'de> de::Deserialize<'de> for NonEmptyString {
22 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
23 where
24 D: serde::Deserializer<'de>,
25 {
26 deserializer.deserialize_string(NonEmptyStringVisitor)
27 }
28}
29
30impl<'de> Visitor<'de> for NonEmptyStringVisitor {
31 type Value = NonEmptyString;
32
33 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34 formatter.write_str("a string with a length of more than 0")
35 }
36
37 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
38 where
39 E: de::Error,
40 {
41 self.visit_string(value.to_owned())
42 }
43
44 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
45 where
46 E: de::Error,
47 {
48 NonEmptyString::new(value).map_err(|e| de::Error::invalid_value(Unexpected::Str(&e), &self))
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::*;
55 use assert_matches::assert_matches;
56 use serde_json::json;
57
58 #[test]
59 fn serialize_non_empty_string_and_normal_string_give_the_same_result() {
60 let value = NonEmptyString("abc".to_owned());
61 let result = serde_json::to_string(&value);
62
63 assert!(result.is_ok());
64
65 let json = serde_json::to_string(&json!("abc")).unwrap();
66 assert_eq!(result.unwrap(), json)
67 }
68
69 #[test]
70 fn deserialize_works() {
71 let e: Result<NonEmptyString, _> = serde_json::from_value(json!("abc"));
72
73 let expected = NonEmptyString("abc".to_owned());
74
75 assert_matches!(e, Ok(v) if v == expected)
76 }
77
78 fn deserialize_x_fails(value: serde_json::Value, expected_error_message: &'static str) {
79 let e: Result<NonEmptyString, _> = serde_json::from_value(value);
80 assert_matches!(e, Err(error) if &error.to_string() == expected_error_message)
81 }
82
83 #[test]
84 fn deserialize_empty_fails() {
85 deserialize_x_fails(
86 json!(""),
87 "invalid value: string \"\", expected a string with a length of more than 0",
88 )
89 }
90
91 #[test]
92 fn deserialize_number_fails() {
93 deserialize_x_fails(
94 json!(8),
95 "invalid type: integer `8`, expected a string with a length of more than 0",
96 )
97 }
98
99 #[test]
100 fn deserialize_object_fails() {
101 deserialize_x_fails(
102 json!({}),
103 "invalid type: map, expected a string with a length of more than 0",
104 )
105 }
106
107 #[test]
108 fn deserialize_sequence_fails() {
109 deserialize_x_fails(
110 json!([]),
111 "invalid type: sequence, expected a string with a length of more than 0",
112 )
113 }
114}