diff options
Diffstat (limited to 'pkgs/by-name/yt/yt/src/select/selection_file/mod.rs')
-rw-r--r-- | pkgs/by-name/yt/yt/src/select/selection_file/mod.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/pkgs/by-name/yt/yt/src/select/selection_file/mod.rs b/pkgs/by-name/yt/yt/src/select/selection_file/mod.rs new file mode 100644 index 00000000..957fcd08 --- /dev/null +++ b/pkgs/by-name/yt/yt/src/select/selection_file/mod.rs @@ -0,0 +1,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)) +} |