use std::io; use std::fs::File; use argparse::{ArgumentParser, StoreTrue, Store}; use crate::options::Options; use crate::id3v2::{ID3v2, Frame}; mod encoding; mod error; mod id3v2; mod options; mod util; fn parse_options_into(opt: &mut Options) { let mut ap = ArgumentParser::new(); ap.set_description("ID3v2 tag editor/fixer. Incomplete/work-in-progress."); ap.refer(&mut opt.write) .add_option(&["-w", "--write"], StoreTrue, "Write updated information instead of just displaying. Unmodified or unknown tags are preserved as-is."); ap.refer(&mut opt.latin1_as_utf8) .add_option(&["--assume-utf8"], StoreTrue, "Assume that all strings specified in the MP3 as Latin-1 are really UTF-8."); ap.refer(&mut opt.set_tags.album) .add_option(&["-A", "--album"], Store, "Set/replace album"); ap.refer(&mut opt.set_tags.artist).add_option(&["-a", "--artist"], Store, "Set/replace artist"); ap.refer(&mut opt.set_tags.title) .add_option(&["-t", "--title"], Store, "Set/replace title"); ap.refer(&mut opt.set_tags.track) .add_option(&["-T", "--track"], Store, "Set/replace track number (num or num/num)"); ap.refer(&mut opt.set_tags.year) .add_option(&["-y", "--year"], Store, "Set/replace year"); ap.refer(&mut opt.file) .required() .add_argument("file", Store, "File to operate on (probably a .mp3)"); ap.parse_args_or_exit(); } fn parse_options() -> Options { let mut options = Default::default(); parse_options_into(&mut options); options } fn print_tag(tag: &ID3v2) -> io::Result<()> { for frame in &tag.frames { match frame.interpret()? { Some(Frame::TALB(album)) => println!("Album : '{}'", album), Some(Frame::TIT2(title)) => println!("Title : '{}'", title), Some(Frame::TPE1(artist)) => println!("Artist: '{}'", artist), Some(Frame::TYER(year)) => println!("Year : '{}'", year), Some(Frame::TRCK(track)) => println!("Track : '{}'", track), None => { println!("Unknown frame: {:?}", frame); } } } Ok(()) } fn main() -> io::Result<()> { let options = parse_options(); let tag = ID3v2::from_stream(&mut File::open(options.file)?)?; // println!("{:?}", tag); // TODO: apply changes from options here // Use RawFrame::map_string print_tag(&tag)?; // TODO: if -w, then write tags to file (if it fits) Ok(()) }