diff --git a/src/input/file.rs b/src/input/file.rs new file mode 100644 index 0000000..ecd916f --- /dev/null +++ b/src/input/file.rs @@ -0,0 +1,65 @@ +//! 本地檔案輸入 + +use anyhow::Result; +use std::path::{Path, PathBuf}; + +#[derive(Debug, Clone)] +pub enum MediaType { + Video, + Audio, + Image, + Document, + Unknown, +} + +impl MediaType { + pub fn from_extension(ext: &str) -> Self { + match ext.to_lowercase().as_str() { + "mp4" | "avi" | "mkv" | "mov" | "webm" | "flv" => MediaType::Video, + "mp3" | "wav" | "flac" | "aac" | "ogg" | "m4a" => MediaType::Audio, + "jpg" | "jpeg" | "png" | "gif" | "webp" | "bmp" => MediaType::Image, + "md" | "markdown" | "pdf" | "html" | "htm" => MediaType::Document, + _ => MediaType::Unknown, + } + } +} + +pub struct FileInput { + path: Option, + media_type: MediaType, +} + +impl FileInput { + pub fn new() -> Self { + Self { + path: None, + media_type: MediaType::Unknown, + } + } + + pub fn open(&mut self, path: &str) -> Result { + let path = Path::new(path); + + if !path.exists() { + anyhow::bail!("File not found: {:?}", path); + } + + let ext = path.extension() + .and_then(|e| e.to_str()) + .unwrap_or(""); + + let media_type = MediaType::from_extension(ext); + self.path = Some(path.to_path_buf()); + self.media_type = media_type.clone(); + + Ok(media_type) + } + + pub fn get_path(&self) -> Option<&Path> { + self.path.as_deref() + } + + pub fn get_media_type(&self) -> &MediaType { + &self.media_type + } +}