1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
//! The data structures needed to express the file, which the user edits
use anyhow::{bail, Context};
use url::Url;
use crate::{app::App, storage::video_database::extractor_hash::ExtractorHash};
pub mod display;
pub mod duration;
pub enum LineCommand {
Pick,
Drop,
Watch,
Url,
}
impl std::str::FromStr for LineCommand {
type Err = anyhow::Error;
fn from_str(v: &str) -> Result<Self, <Self as std::str::FromStr>::Err> {
match v {
"pick" | "p" => Ok(Self::Pick),
"drop" | "d" => Ok(Self::Drop),
"watch" | "w" => Ok(Self::Watch),
"url" | "u" => Ok(Self::Url),
other => bail!("'{}' is not a recognized command!", other),
}
}
}
pub struct Line {
pub cmd: LineCommand,
pub hash: ExtractorHash,
pub url: Url,
}
impl Line {
pub async fn from_str(app: &App, s: &str) -> anyhow::Result<Self> {
let buf: Vec<_> = s.split_whitespace().collect();
let url_as_str = buf
.last()
.with_context(|| format!("The line '{}' misses it's url field!'", s))?
.trim_matches('"');
let url: Url = Url::parse(url_as_str)
.with_context(|| format!("The url '{}' could not be parsed!", url_as_str))?;
Ok(Line {
cmd: buf
.get(0)
.with_context(|| format!("The line '{}' is missing it's command!", s))?
.parse()?,
hash: ExtractorHash::parse_from_short_version(
app,
buf.get(1)
.with_context(|| format!("The line '{}' is missing it's blake3 hash!", s))?,
)
.await
.with_context(|| {
format!(
"Can't parse '{}' as blake3 hash!",
buf.get(1).expect("Already checked"),
)
})?,
url,
})
}
}
pub async fn filter_line(app: &App, line: &str) -> anyhow::Result<Option<Line>> {
// Filter out comments and empty lines
if line.starts_with('#') || line.trim().is_empty() {
return Ok(None);
}
let line: Line = Line::from_str(app, line).await?;
Ok(Some(line))
}
|