lazily-evaluated extractors
This commit is contained in:
68
crates/pile-dataset/src/extract/mod.rs
Normal file
68
crates/pile-dataset/src/extract/mod.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
mod flac;
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
pub use flac::*;
|
||||
|
||||
mod fs;
|
||||
pub use fs::*;
|
||||
|
||||
mod map;
|
||||
pub use map::*;
|
||||
use pile_config::Label;
|
||||
|
||||
/// An attachment that extracts metadata from an [Item].
|
||||
///
|
||||
/// Metadata is exposed as an immutable map of {label: value},
|
||||
/// much like a json object.
|
||||
pub trait Extractor<I: crate::Item> {
|
||||
/// Get the field at `name` from `item`.
|
||||
/// - returns `None` if `name` is not a valid field
|
||||
/// - returns `Some(Null)` if `name` is not available
|
||||
fn field<'a>(
|
||||
&'a self,
|
||||
name: &pile_config::Label,
|
||||
) -> Result<Option<&'a crate::PileValue<'a, I>>, std::io::Error>;
|
||||
|
||||
/// Return all fields in this extractor.
|
||||
/// `Self::field` must return [Some] for all these keys
|
||||
/// and [None] for all others.
|
||||
fn fields(&self) -> Result<Vec<Label>, std::io::Error>;
|
||||
}
|
||||
|
||||
pub struct MetaExtractor<'a, I: crate::Item> {
|
||||
inner: MapExtractor<'a, I>,
|
||||
}
|
||||
|
||||
impl<'a> MetaExtractor<'a, crate::FileItem> {
|
||||
#[expect(clippy::unwrap_used)]
|
||||
pub fn new(item: &'a crate::FileItem) -> Self {
|
||||
let inner = MapExtractor {
|
||||
inner: HashMap::from([
|
||||
(
|
||||
Label::new("flac").unwrap(),
|
||||
crate::PileValue::Extractor(Rc::new(FlacExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("fs").unwrap(),
|
||||
crate::PileValue::Extractor(Rc::new(FsExtractor::new(item))),
|
||||
),
|
||||
]),
|
||||
};
|
||||
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl Extractor<crate::FileItem> for MetaExtractor<'_, crate::FileItem> {
|
||||
fn field<'a>(
|
||||
&'a self,
|
||||
name: &pile_config::Label,
|
||||
) -> Result<Option<&'a crate::PileValue<'a, crate::FileItem>>, std::io::Error> {
|
||||
self.inner.field(name)
|
||||
}
|
||||
|
||||
#[expect(clippy::unwrap_used)]
|
||||
fn fields(&self) -> Result<Vec<Label>, std::io::Error> {
|
||||
return Ok(vec![Label::new("flac").unwrap(), Label::new("fs").unwrap()]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user