1use serde::ser::{
20 self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
21 SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
22};
23use snafu::Snafu;
24use std::fmt::Display;
25
26#[derive(Debug, Snafu)]
28pub enum Error {
29 #[snafu(display("Failed to serialize object: {}", msg))]
30 SerializationError { msg: String },
31}
32
33impl serde::ser::Error for Error {
34 fn custom<T>(msg: T) -> Self
35 where
36 T: Display,
37 {
38 Self::SerializationError {
39 msg: msg.to_string(),
40 }
41 }
42}
43
44pub struct Serializer {
46 args: Vec<String>,
48 boolean_type: BooleanType,
50}
51
52pub enum BooleanType {
54 TrueFalse,
56 OnOff,
58}
59
60impl Serializer {
61 pub fn new(boolean_type: BooleanType) -> Self {
63 Self {
64 args: vec![],
65 boolean_type,
66 }
67 }
68
69 pub fn into_args<T>(mut self, value: &T) -> Result<Vec<String>, Error>
71 where
72 T: Serialize,
73 {
74 value.serialize(&mut self)?;
75 Ok(self.args)
76 }
77}
78
79pub fn to_args<T>(value: &T) -> Result<Vec<String>, Error>
81where
82 T: Serialize,
83{
84 Serializer::new(BooleanType::TrueFalse).into_args(value)
85}
86
87impl<'a> ser::Serializer for &'a mut Serializer {
88 type Ok = ();
89 type Error = Error;
90 type SerializeSeq = Self;
91 type SerializeTuple = Self;
92 type SerializeTupleStruct = Self;
93 type SerializeTupleVariant = Self;
94 type SerializeMap = Self;
95 type SerializeStruct = Self;
96 type SerializeStructVariant = Self;
97
98 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
99 self.args.push(
100 match self.boolean_type {
101 BooleanType::TrueFalse => {
102 if v {
103 "true"
104 } else {
105 "false"
106 }
107 }
108 BooleanType::OnOff => {
109 if v {
110 "on"
111 } else {
112 "off"
113 }
114 }
115 }
116 .into(),
117 );
118 Ok(())
119 }
120
121 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
122 self.serialize_i64(i64::from(v))
123 }
124
125 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
126 self.serialize_i64(i64::from(v))
127 }
128
129 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
130 self.serialize_i64(i64::from(v))
131 }
132
133 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
134 self.args.push(v.to_string());
135 Ok(())
136 }
137
138 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
139 self.serialize_u64(u64::from(v))
140 }
141
142 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
143 self.serialize_u64(u64::from(v))
144 }
145
146 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
147 self.serialize_u64(u64::from(v))
148 }
149
150 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
151 self.args.push(v.to_string());
152 Ok(())
153 }
154
155 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
156 self.serialize_f64(f64::from(v))
157 }
158
159 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
160 self.args.push(v.to_string());
161 Ok(())
162 }
163
164 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
165 self.serialize_str(&v.to_string())
166 }
167
168 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
169 self.args.push(v.into());
170 Ok(())
171 }
172
173 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
174 unimplemented!()
175 }
176
177 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
178 self.args.pop();
179 self.serialize_unit()
180 }
181
182 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
183 where
184 T: Serialize,
185 {
186 value.serialize(self)
187 }
188
189 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
190 Ok(())
192 }
193
194 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
195 self.serialize_unit()
196 }
197
198 fn serialize_unit_variant(
199 self,
200 _name: &'static str,
201 _variant_index: u32,
202 variant: &'static str,
203 ) -> Result<Self::Ok, Self::Error> {
204 self.serialize_str(variant)
205 }
206
207 fn serialize_newtype_struct<T: ?Sized>(
208 self,
209 _name: &'static str,
210 value: &T,
211 ) -> Result<Self::Ok, Self::Error>
212 where
213 T: Serialize,
214 {
215 value.serialize(self)
216 }
217
218 fn serialize_newtype_variant<T: ?Sized>(
219 self,
220 _name: &'static str,
221 _variant_index: u32,
222 variant: &'static str,
223 value: &T,
224 ) -> Result<Self::Ok, Self::Error>
225 where
226 T: Serialize,
227 {
228 variant.serialize(&mut *self)?;
229 value.serialize(&mut *self)?;
230 Ok(())
231 }
232
233 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
234 self.args.pop();
235 Ok(self)
236 }
237
238 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
239 self.serialize_seq(Some(len))
240 }
241
242 fn serialize_tuple_struct(
243 self,
244 _name: &'static str,
245 len: usize,
246 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
247 self.serialize_seq(Some(len))
248 }
249
250 fn serialize_tuple_variant(
251 self,
252 _name: &'static str,
253 _variant_index: u32,
254 variant: &'static str,
255 _len: usize,
256 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
257 variant.serialize(&mut *self)?;
258 Ok(self)
259 }
260
261 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
262 Ok(self)
263 }
264
265 fn serialize_struct(
266 self,
267 _name: &'static str,
268 len: usize,
269 ) -> Result<Self::SerializeStruct, Self::Error> {
270 self.serialize_map(Some(len))
271 }
272
273 fn serialize_struct_variant(
274 self,
275 _name: &'static str,
276 _variant_index: u32,
277 variant: &'static str,
278 _len: usize,
279 ) -> Result<Self::SerializeStructVariant, Self::Error> {
280 variant.serialize(&mut *self)?;
281 Ok(self)
282 }
283
284 fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
285 where
286 T: Display,
287 {
288 unimplemented!()
289 }
290}
291
292impl<'a> SerializeSeq for &'a mut Serializer {
293 type Ok = ();
294 type Error = Error;
295
296 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
297 where
298 T: Serialize,
299 {
300 value.serialize(&mut **self)
301 }
302
303 fn end(self) -> Result<Self::Ok, Self::Error> {
304 Ok(())
305 }
306}
307
308impl<'a> SerializeTuple for &'a mut Serializer {
309 type Ok = ();
310 type Error = Error;
311
312 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
313 where
314 T: Serialize,
315 {
316 value.serialize(&mut **self)
317 }
318
319 fn end(self) -> Result<Self::Ok, Self::Error> {
320 Ok(())
321 }
322}
323
324impl<'a> SerializeTupleStruct for &'a mut Serializer {
325 type Ok = ();
326 type Error = Error;
327
328 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
329 where
330 T: Serialize,
331 {
332 value.serialize(&mut **self)
333 }
334
335 fn end(self) -> Result<Self::Ok, Self::Error> {
336 Ok(())
337 }
338}
339
340impl<'a> SerializeTupleVariant for &'a mut Serializer {
341 type Ok = ();
342 type Error = Error;
343
344 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
345 where
346 T: Serialize,
347 {
348 value.serialize(&mut **self)
349 }
350
351 fn end(self) -> Result<Self::Ok, Self::Error> {
352 Ok(())
353 }
354}
355
356impl<'a> SerializeMap for &'a mut Serializer {
357 type Ok = ();
358 type Error = Error;
359
360 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
361 where
362 T: Serialize,
363 {
364 key.serialize(&mut **self)
365 }
366
367 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
368 where
369 T: Serialize,
370 {
371 value.serialize(&mut **self)
372 }
373
374 fn end(self) -> Result<Self::Ok, Self::Error> {
375 Ok(())
376 }
377}
378
379impl<'a> SerializeStruct for &'a mut Serializer {
380 type Ok = ();
381 type Error = Error;
382
383 fn serialize_field<T: ?Sized>(
384 &mut self,
385 key: &'static str,
386 value: &T,
387 ) -> Result<(), Self::Error>
388 where
389 T: Serialize,
390 {
391 key.serialize(&mut **self)?;
392 value.serialize(&mut **self)
393 }
394
395 fn end(self) -> Result<Self::Ok, Self::Error> {
396 Ok(())
397 }
398}
399
400impl<'a> SerializeStructVariant for &'a mut Serializer {
401 type Ok = ();
402 type Error = Error;
403
404 fn serialize_field<T: ?Sized>(
405 &mut self,
406 key: &'static str,
407 value: &T,
408 ) -> Result<(), Self::Error>
409 where
410 T: Serialize,
411 {
412 key.serialize(&mut **self)?;
413 value.serialize(&mut **self)
414 }
415
416 fn end(self) -> Result<Self::Ok, Self::Error> {
417 Ok(())
418 }
419}
420
421#[cfg(test)]
422mod tests {
423 use super::*;
424 use maplit::hashmap;
425 use serde::Serialize;
426 use std::collections::HashMap;
427
428 #[test]
429 fn test_simple_struct() {
430 #[derive(Serialize)]
431 struct Test {
432 signed_int: i32,
433 unsigned_int: u32,
434 string: String,
435 character: char,
436 }
437
438 let options = to_args(&Test {
439 signed_int: -10,
440 unsigned_int: 10,
441 string: String::from("Hello World"),
442 character: 'X',
443 })
444 .unwrap();
445
446 let expected: Vec<String> = vec![
447 "signed_int".into(),
448 "-10".into(),
449 "unsigned_int".into(),
450 "10".into(),
451 "string".into(),
452 "Hello World".into(),
453 "character".into(),
454 "X".into(),
455 ];
456 assert_eq!(options, expected);
457 }
458
459 #[test]
460 fn test_nested_list() {
461 #[derive(Serialize)]
462 struct Test {
463 example: i32,
464 opts: Vec<String>,
465 }
466
467 let options = to_args(&Test {
468 example: 1,
469 opts: vec!["a".into(), "b".into(), "c".into()],
470 })
471 .unwrap();
472
473 let expected: Vec<String> = vec![
474 "example".into(),
475 "1".into(),
476 "a".into(),
477 "b".into(),
478 "c".into(),
479 ];
480 assert_eq!(options, expected);
481 }
482
483 #[test]
484 fn test_nested_map() {
485 #[derive(Serialize)]
486 struct Test {
487 example: i32,
488 fields: HashMap<String, i32>,
489 }
490
491 let options = to_args(&Test {
492 example: 1,
493 fields: hashmap! {
494 "a".into() => 1,
495 "b".into() => 2,
496 },
497 })
498 .unwrap();
499
500 let expected: Vec<String> = vec![
501 "example".into(),
502 "1".into(),
503 "fields".into(),
504 "a".into(),
505 "1".into(),
506 "b".into(),
507 "2".into(),
508 ];
509 assert_eq!(options, expected);
510 }
511
512 #[test]
513 fn test_boolean_modes() {
514 #[derive(Serialize)]
515 struct Test {
516 #[serde(rename = "my-feature")]
517 feature: bool,
518 }
519
520 let options = Serializer::new(BooleanType::OnOff)
521 .into_args(&Test { feature: true })
522 .unwrap();
523
524 let expected: Vec<String> = vec!["my-feature".into(), "on".into()];
525 assert_eq!(options, expected);
526 }
527
528 #[test]
529 fn test_optional_field() {
530 #[derive(Serialize)]
531 struct Test {
532 name: Option<String>,
533 }
534
535 let options = to_args(&Test {
536 name: Some("Alice".into()),
537 })
538 .unwrap();
539
540 let expected: Vec<String> = vec!["name".into(), "Alice".into()];
541 assert_eq!(options, expected);
542
543 let options = to_args(&Test { name: None }).unwrap();
544
545 let expected: Vec<String> = vec![];
546 assert_eq!(options, expected);
547 }
548}