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