use std::ops::Deref; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct AudioMetadata(pub serde_json::Value); impl From for mongodb::bson::Bson { fn from(val: AudioMetadata) -> Self { mongodb::bson::to_bson(&val.0).unwrap() } } impl AudioMetadata { fn get_key(&self, key: &str) -> Option<&str> { self.0.as_object()?.get(key)?.as_str() } pub fn title(&self) -> Option<&str> { self.get_key("title") } pub fn artist(&self) -> Option<&str> { self.get_key("artist") } pub fn album(&self) -> Option<&str> { self.get_key("album") } pub fn track_number(&self) -> Option { self.get_key("tracknumber").map(|x| x.parse().ok())? } } pub fn get_metadata(file_path: &str) -> Option { Some(AudioMetadata(get_metadata_json(file_path)?)) } pub fn get_metadata_json(file_path: &str) -> Option { let output = std::process::Command::new("python3") .arg("./extract_metadata.py") .arg(file_path) .output() .ok()?; let stdout = String::from_utf8_lossy(&output.stdout); serde_json::from_str(&stdout).ok()? } impl Deref for AudioMetadata { type Target = serde_json::Value; fn deref(&self) -> &Self::Target { &self.0 } }