use std::fmt;
use qsv_docopt::Docopt;
use serde::{
de::{Deserializer, Error, Visitor},
Deserialize,
};
const USAGE: &str = "
Rust's package manager
Usage:
mycli [<command>]
Options:
-h, --help Display this message
";
#[derive(Debug, Deserialize)]
struct Args {
arg_command: Command,
}
struct CommandVisitor;
impl<'de> Visitor<'de> for CommandVisitor {
type Value = Command;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string A, B or C")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(match s {
"" => Command::None,
"A" => Command::A,
"B" => Command::B,
"C" => Command::C,
s => Command::Unknown(s.to_string()),
})
}
}
impl<'de> Deserialize<'de> for Command {
fn deserialize<D>(d: D) -> Result<Command, D::Error>
where
D: Deserializer<'de>,
{
d.deserialize_str(CommandVisitor)
}
}
#[derive(Debug)]
enum Command {
A,
B,
C,
Unknown(String),
None,
}
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);
}