pinakes/crates/pinakes-core/src/metadata/mod.rs
NotAShelf 185e3b562a
treewide: cleanup
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ia01590cdeed872cc8ebd16f6ca95f3cc6a6a6964
2026-03-12 19:41:15 +03:00

68 lines
1.9 KiB
Rust

pub mod audio;
pub mod document;
pub mod image;
pub mod markdown;
pub mod video;
use std::{collections::HashMap, path::Path};
use crate::{error::Result, media_type::MediaType, model::BookMetadata};
#[derive(Debug, Clone, Default)]
pub struct ExtractedMetadata {
pub title: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
pub genre: Option<String>,
pub year: Option<i32>,
pub duration_secs: Option<f64>,
pub description: Option<String>,
pub extra: HashMap<String, String>,
pub book_metadata: Option<BookMetadata>,
// Photo-specific metadata
pub date_taken: Option<chrono::DateTime<chrono::Utc>>,
pub latitude: Option<f64>,
pub longitude: Option<f64>,
pub camera_make: Option<String>,
pub camera_model: Option<String>,
pub rating: Option<i32>,
}
pub trait MetadataExtractor: Send + Sync {
/// Extract metadata from a file at the given path.
///
/// # Errors
///
/// Returns an error if the file cannot be read or parsed.
fn extract(&self, path: &Path) -> Result<ExtractedMetadata>;
fn supported_types(&self) -> Vec<MediaType>;
}
/// Extract metadata from a file using the appropriate extractor for the given
/// media type.
///
/// # Errors
///
/// Returns an error if no extractor supports the media type, or if extraction
/// fails.
pub fn extract_metadata(
path: &Path,
media_type: &MediaType,
) -> Result<ExtractedMetadata> {
let extractors: Vec<Box<dyn MetadataExtractor>> = vec![
Box::new(audio::AudioExtractor),
Box::new(document::DocumentExtractor),
Box::new(video::VideoExtractor),
Box::new(markdown::MarkdownExtractor),
Box::new(image::ImageExtractor),
];
for extractor in &extractors {
if extractor.supported_types().contains(media_type) {
return extractor.extract(path);
}
}
Ok(ExtractedMetadata::default())
}