use lofty::config::WriteOptions; use lofty::prelude::ItemKey::AlbumTitle; use lofty::tag::TagItem; use lofty::tag::TagType::VorbisComments; use lofty::tag::{ItemKey, ItemValue}; use lofty::tag::{Tag, TagExt}; use std::collections::HashMap; use std::env::var; use std::io::Write; use std::path::PathBuf; use std::{fs::File, io::Read, process::Command}; pub fn edit(file_path: PathBuf, mut tag: Tag) -> std::io::Result<()> { let tmp_file = PathBuf::from("/tmp/keks-sort-metadata"); let editor = var("EDITOR").unwrap(); let mut file = File::create(&tmp_file)?; for item in tag.items() { writeln!( file, "{} = {}", item.key().map_key(VorbisComments).unwrap(), item.value().text().unwrap() )?; } Command::new(editor) .arg(&tmp_file) .status() .expect("Something went wrong"); let mut editable = String::new(); File::open(&tmp_file) .expect("Could not open file") .read_to_string(&mut editable)?; let parsed = parse(&editable); for (key, value) in parsed { let item_key = ItemKey::from_key(VorbisComments, &key).expect("Failed to get item key"); let item = TagItem::new(item_key, ItemValue::Text(value)); tag.insert(item.clone()); } tag.save_to_path(file_path, WriteOptions::default()) .expect("ERROR: Failed to write tag"); Ok(()) } fn parse(input: &str) -> HashMap { input .lines() .filter_map(|line| { let (key, value) = line.split_once('=')?; Some((key.trim().to_string(), value.trim().to_string())) }) .collect() }