1use std::fmt;
4
5use serde::{
6 de::{Error, SeqAccess, Visitor},
7 ser::SerializeSeq,
8 Deserialize, Deserializer, Serialize, Serializer,
9};
10
11use crate::command::Command;
12
13impl Serialize for Command {
14 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
15 let args = self.get_args();
16 let args_len = match &args {
17 Some(args) => args.len() + 1,
18 None => 0,
19 };
20
21 let mut seq = serializer.serialize_seq(Some(args_len))?;
22
23 seq.serialize_element(&self.get_program())?;
24
25 if let Some(args) = args {
26 for arg in args {
27 seq.serialize_element(&arg)?;
28 }
29 }
30
31 seq.end()
32 }
33}
34
35impl<'de> Deserialize<'de> for Command {
36 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Command, D::Error> {
37 deserializer.deserialize_any(CommandVisitor)
38 }
39}
40
41struct CommandVisitor;
42
43impl<'de> Visitor<'de> for CommandVisitor {
44 type Value = Command;
45
46 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
47 formatter.write_str("a string (full command) or a list of string (command arguments)")
48 }
49
50 fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
51 let mut args = v.split_whitespace();
52 let program = args.next().ok_or(E::custom("command cannot be empty"))?;
53 let mut command = Command::new(program);
54 command.args(args);
55 Ok(command)
56 }
57
58 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
59 let program = seq
60 .next_element::<String>()?
61 .ok_or(<A::Error as Error>::custom("command cannot be empty"))?;
62
63 let mut command = Command::new(program);
64
65 while let Some(arg) = seq.next_element::<String>()? {
66 command.arg(arg);
67 }
68
69 Ok(command)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use serde::{
76 de::value::{Error, SeqDeserializer, StringDeserializer},
77 Deserialize,
78 };
79
80 use crate::command::Command;
81
82 #[test]
90 fn deserialize_string() {
91 let mut expected = Command::new("program");
92 expected.arg("arg1").arg("arg2");
93
94 let s = String::from("program arg1 arg2");
95 let s = StringDeserializer::<Error>::new(s);
96 let got = Command::deserialize(s).unwrap();
97 assert_eq!(expected, got);
98
99 let s = String::from("program \narg1 \t arg2");
100 let s = StringDeserializer::<Error>::new(s);
101 let got = Command::deserialize(s).unwrap();
102 assert_eq!(expected, got);
103 }
104
105 #[test]
106 fn deserialize_empty_string() {
107 let s = StringDeserializer::<Error>::new(String::new());
108 let err = Command::deserialize(s).unwrap_err();
109 assert_eq!("command cannot be empty", err.to_string());
110
111 let s = StringDeserializer::<Error>::new(String::from(" \n\t"));
112 let err = Command::deserialize(s).unwrap_err();
113 assert_eq!("command cannot be empty", err.to_string());
114 }
115
116 #[test]
117 fn deserialize_seq() {
118 let mut expected = Command::new("program");
119 expected.arg("arg1").arg("arg2");
120
121 let s = ["program", "arg1", "arg2"];
122 let s = SeqDeserializer::<_, Error>::new(s.into_iter());
123 let got = Command::deserialize(s).unwrap();
124 assert_eq!(expected, got);
125 }
126
127 #[test]
128 fn deserialize_empty_seq() {
129 let s: [&str; 0] = [];
130 let s = SeqDeserializer::new(s.into_iter());
131 let err: Error = Command::deserialize(s).unwrap_err();
132 assert_eq!("command cannot be empty", err.to_string());
133 }
134}