Add ListExtractor
This commit is contained in:
@@ -35,7 +35,7 @@ use crate::Item;
|
||||
/// Metadata is exposed as an immutable map of {label: value},
|
||||
/// much like a json object.
|
||||
#[async_trait::async_trait]
|
||||
pub trait Extractor: Send + Sync {
|
||||
pub trait ObjectExtractor: Send + Sync {
|
||||
/// Get the field at `name` from `item`.
|
||||
/// - returns `None` if `name` is not a valid field
|
||||
/// - returns `Some(Null)` if `name` is not available
|
||||
@@ -50,14 +50,31 @@ pub trait Extractor: Send + Sync {
|
||||
async fn fields(&self) -> Result<Vec<Label>, std::io::Error>;
|
||||
}
|
||||
|
||||
/// An attachment that extracts metadata from an [Item].
|
||||
///
|
||||
/// Metadata is exposed as an immutable list of values.
|
||||
#[async_trait::async_trait]
|
||||
pub trait ListExtractor: Send + Sync {
|
||||
/// Get the item at index `idx`.
|
||||
/// Indices start at zero, and must be consecutive.
|
||||
/// - returns `None` if `idx` is out of range
|
||||
/// - returns `Some(Null)` if `None` is at `idx`
|
||||
async fn get<'a>(
|
||||
&'a self,
|
||||
idx: usize,
|
||||
) -> Result<Option<&'a crate::PileValue<'a>>, std::io::Error>;
|
||||
|
||||
async fn len(&self) -> Result<usize, std::io::Error>;
|
||||
|
||||
async fn is_empty(&self) -> Result<bool, std::io::Error> {
|
||||
Ok(self.len().await? == 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MetaExtractor<'a> {
|
||||
inner: MapExtractor<'a>,
|
||||
}
|
||||
|
||||
//
|
||||
// MARK: file
|
||||
//
|
||||
|
||||
impl<'a> MetaExtractor<'a> {
|
||||
#[expect(clippy::unwrap_used)]
|
||||
pub fn new(item: &'a Item) -> Self {
|
||||
@@ -65,35 +82,35 @@ impl<'a> MetaExtractor<'a> {
|
||||
inner: HashMap::from([
|
||||
(
|
||||
Label::new("flac").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(FlacExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(FlacExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("id3").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(Id3Extractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(Id3Extractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("fs").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(FsExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(FsExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("epub").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(EpubExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(EpubExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("exif").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(ExifExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(ExifExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("pdf").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(PdfExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(PdfExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("toml").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(TomlExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(TomlExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("sidecar").unwrap(),
|
||||
crate::PileValue::Extractor(Arc::new(SidecarExtractor::new(item))),
|
||||
crate::PileValue::ObjectExtractor(Arc::new(SidecarExtractor::new(item))),
|
||||
),
|
||||
]),
|
||||
};
|
||||
@@ -103,7 +120,7 @@ impl<'a> MetaExtractor<'a> {
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Extractor for MetaExtractor<'_> {
|
||||
impl ObjectExtractor for MetaExtractor<'_> {
|
||||
async fn field<'a>(
|
||||
&'a self,
|
||||
name: &pile_config::Label,
|
||||
|
||||
Reference in New Issue
Block a user