|
1 | 1 | use structopt::StructOpt; |
| 2 | +use std::str::FromStr; |
| 3 | +use std::fmt::{Display, Formatter}; |
2 | 4 |
|
3 | 5 | #[derive(Debug, StructOpt)] |
4 | 6 | #[structopt(name = "rustcli", about = "Rust CLI examples with StructOpt")] |
5 | | -enum Opt { |
6 | | - #[structopt(about = "Create a new entity")] |
7 | | - Create { |
8 | | - title: String, |
9 | | - text: Option<String> |
10 | | - }, |
11 | | - #[structopt(about = "Edit an existing entity")] |
12 | | - Edit { |
13 | | - id: i32, |
14 | | - title: Option<String>, |
15 | | - text: Option<String> |
16 | | - }, |
17 | | - #[structopt(about = "List all entities")] |
18 | | - List |
| 7 | +struct Opt { |
| 8 | + #[structopt(help = "Status of the task (todo, inprogress, blocked, done)")] |
| 9 | + status: Status |
| 10 | +} |
| 11 | + |
| 12 | +#[derive(Debug)] |
| 13 | +enum Status { |
| 14 | + ToDo, |
| 15 | + InProgress, |
| 16 | + Done, |
| 17 | + Blocked |
| 18 | +} |
| 19 | + |
| 20 | +impl FromStr for Status { |
| 21 | + // TODO: understand why I need this line |
| 22 | + type Err = ParseError; |
| 23 | + |
| 24 | + fn from_str(s: &str) -> Result<Self, Self::Err> { |
| 25 | + // TODO: understand how to convert to lowercase here without String::from later |
| 26 | + match s { |
| 27 | + "todo" => Ok(Status::ToDo), |
| 28 | + "inprogress" => Ok(Status::InProgress), |
| 29 | + "blocked" => Ok(Status::Blocked), |
| 30 | + "done" => Ok(Status::Done), |
| 31 | + // TODO: understand how to simplify this |
| 32 | + _ => Err(ParseError(String::from("Status must be one of the following: todo, inprogress, blocked, or done."))) |
| 33 | + } |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +// TODO: research ways to reuse well-known errors |
| 38 | +#[derive(Debug)] |
| 39 | +struct ParseError(String); |
| 40 | +// TODO: understand the difference between std::error::Error and std::fmt::Error |
| 41 | +impl std::error::Error for ParseError { } |
| 42 | +impl Display for ParseError { |
| 43 | + // TODO: understand why lifetime specifier is required here |
| 44 | + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { |
| 45 | + write!(f, "{}", self.0) |
| 46 | + } |
19 | 47 | } |
20 | 48 |
|
21 | 49 | fn main() { |
22 | 50 | let opt = Opt::from_args(); |
23 | 51 | println!("opt = {:?}", opt); |
24 | | - match opt { |
25 | | - Opt::Create { title, text } => println!("Processing Opt::Create with title = {}, text = {:?}", title, text), |
26 | | - Opt::Edit { .. } => println!("Processing Opt::Edit with {:?}", opt), |
27 | | - Opt::List => println!("Processing Opt::List"), |
28 | | - } |
29 | 52 | } |
0 commit comments