1use crate::JsonBackend;
4use docspec_core::Result;
5
6#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
8pub struct Null;
9
10pub trait WriteVal {
12 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()>;
18}
19
20impl WriteVal for &str {
21 #[inline]
22 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()> {
23 backend.write_string(self)
24 }
25}
26
27impl WriteVal for bool {
28 #[inline]
29 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()> {
30 backend.write_bool(self)
31 }
32}
33
34impl WriteVal for u8 {
35 #[inline]
36 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()> {
37 backend.write_number(u32::from(self))
38 }
39}
40
41impl WriteVal for u32 {
42 #[inline]
43 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()> {
44 backend.write_number(self)
45 }
46}
47
48impl WriteVal for Null {
49 #[inline]
50 fn write_to<B: JsonBackend>(self, backend: &mut B) -> Result<()> {
51 backend.write_null()
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use docspec_core::Error;
59
60 #[derive(Default)]
61 struct MockBackend {
62 fail: bool,
63 last_bool: Option<bool>,
64 last_call: &'static str,
65 last_number: Option<u32>,
66 last_string: Option<String>,
67 }
68
69 impl crate::JsonBackend for MockBackend {
70 type Output = ();
71
72 fn begin_array(&mut self) -> docspec_core::Result<()> {
73 Ok(())
74 }
75
76 fn begin_object(&mut self) -> docspec_core::Result<()> {
77 Ok(())
78 }
79
80 fn end_array(&mut self) -> docspec_core::Result<()> {
81 Ok(())
82 }
83
84 fn end_object(&mut self) -> docspec_core::Result<()> {
85 Ok(())
86 }
87
88 fn finish(self) -> docspec_core::Result<()> {
89 Ok(())
90 }
91
92 fn write_bool(&mut self, b: bool) -> docspec_core::Result<()> {
93 self.last_call = "write_bool";
94 self.last_bool = Some(b);
95 Ok(())
96 }
97
98 fn write_name(&mut self, _: &str) -> docspec_core::Result<()> {
99 Ok(())
100 }
101
102 fn write_null(&mut self) -> docspec_core::Result<()> {
103 self.last_call = "write_null";
104 Ok(())
105 }
106
107 fn write_number(&mut self, n: u32) -> docspec_core::Result<()> {
108 self.last_call = "write_number";
109 self.last_number = Some(n);
110 Ok(())
111 }
112
113 fn write_string(&mut self, s: &str) -> docspec_core::Result<()> {
114 self.last_call = "write_string";
115 self.last_string = Some(s.to_string());
116 if self.fail {
117 Err(Error::Other {
118 message: "mock error".to_string(),
119 })
120 } else {
121 Ok(())
122 }
123 }
124 }
125
126 #[test]
127 fn mock_backend_container_methods_callable() {
128 let mut b = MockBackend::default();
129 assert!(b.begin_array().is_ok());
130 assert!(b.begin_object().is_ok());
131 assert!(b.end_array().is_ok());
132 assert!(b.end_object().is_ok());
133 assert!(b.write_name("k").is_ok());
134 }
135
136 #[test]
137 fn mock_backend_finish_callable() {
138 let b = MockBackend::default();
139 assert!(b.finish().is_ok());
140 }
141
142 #[test]
143 fn write_val_bool_false_calls_write_bool_with_false() {
144 let mut b = MockBackend::default();
145 assert!(false.write_to(&mut b).is_ok());
146 assert_eq!(b.last_call, "write_bool");
147 assert_eq!(b.last_bool, Some(false));
148 }
149
150 #[test]
151 fn write_val_bool_true_calls_write_bool_with_true() {
152 let mut b = MockBackend::default();
153 assert!(true.write_to(&mut b).is_ok());
154 assert_eq!(b.last_call, "write_bool");
155 assert_eq!(b.last_bool, Some(true));
156 }
157
158 #[test]
159 fn write_val_null_calls_write_null() {
160 let mut b = MockBackend::default();
161 assert!(Null.write_to(&mut b).is_ok());
162 assert_eq!(b.last_call, "write_null");
163 }
164
165 #[test]
166 fn write_val_propagates_backend_error() {
167 let mut b = MockBackend {
168 fail: true,
169 ..MockBackend::default()
170 };
171 assert!("hello".write_to(&mut b).is_err());
172 }
173
174 #[test]
175 fn write_val_str_calls_write_string() {
176 let mut b = MockBackend::default();
177 assert!("hello".write_to(&mut b).is_ok());
178 assert_eq!(b.last_call, "write_string");
179 assert_eq!(b.last_string.as_deref(), Some("hello"));
180 }
181
182 #[test]
183 fn write_val_u8_calls_write_number() {
184 let mut b = MockBackend::default();
185 let n: u8 = 42;
186 assert!(n.write_to(&mut b).is_ok());
187 assert_eq!(b.last_call, "write_number");
188 assert_eq!(b.last_number, Some(42));
189 }
190
191 #[test]
192 fn write_val_u32_calls_write_number() {
193 let mut b = MockBackend::default();
194 let n: u32 = 42;
195 assert!(n.write_to(&mut b).is_ok());
196 assert_eq!(b.last_call, "write_number");
197 assert_eq!(b.last_number, Some(42));
198 }
199}