io_process/
serde.rs

1//! Module dedicated to [`serde`] de/serialization of [`Command`].
2
3use 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    // TODO
83    //
84    // #[test]
85    // fn serialize() {
86    //
87    // }
88
89    #[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}