1use crate::{Error, Result};
2use std::str::FromStr;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
5pub enum Selection {
6 Current,
7 Latest,
8 All,
9 Episode(u64),
10 Page(u32),
11}
12
13impl FromStr for Selection {
14 type Err = Error;
15
16 fn from_str(raw: &str) -> Result<Self> {
17 let text = raw.trim();
18 let lower = text.to_ascii_lowercase();
19 match lower.as_str() {
20 "current" => Ok(Self::Current),
21 "latest" | "last" | "new" => Ok(Self::Latest),
22 "all" => Ok(Self::All),
23 _ => {
24 if let Some(id) = lower.strip_prefix("episode:") {
25 return parse_u64(id, "episode").map(Self::Episode);
26 }
27 if let Some(page) = lower.strip_prefix("page:") {
28 return parse_u32(page, "page").map(Self::Page);
29 }
30 Err(Error::InvalidInput(format!("invalid selection `{raw}`")))
31 }
32 }
33 }
34}
35
36fn parse_u64(text: &str, label: &str) -> Result<u64> {
37 text.parse::<u64>()
38 .map_err(|_| Error::InvalidInput(format!("invalid {label} selection `{text}`")))
39}
40
41fn parse_u32(text: &str, label: &str) -> Result<u32> {
42 text.parse::<u32>()
43 .map_err(|_| Error::InvalidInput(format!("invalid {label} selection `{text}`")))
44}