diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/src/main.rs b/src/main.rs index 63bbbf0..c2b4c5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ use std::io; use std::fs::File; -use argparse::{ArgumentParser, StoreTrue, Store}; -use crate::options::Options; +use argparse::{ArgumentParser, Store, StoreTrue, StoreOption}; +use crate::error::IntoIOError; use crate::id3v2::{ID3v2, Frame}; +use crate::options::Options; mod encoding; mod error; @@ -22,11 +23,11 @@ fn parse_options_into(opt: &mut Options) { .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.set_tags.album) .add_option(&["-A", "--album"], StoreOption, "Set/replace album"); + ap.refer(&mut opt.set_tags.artist).add_option(&["-a", "--artist"], StoreOption, "Set/replace artist"); + ap.refer(&mut opt.set_tags.title) .add_option(&["-t", "--title"], StoreOption, "Set/replace title"); + ap.refer(&mut opt.set_tags.track) .add_option(&["-T", "--track"], StoreOption, "Set/replace track number (num or num/num)"); + ap.refer(&mut opt.set_tags.year) .add_option(&["-y", "--year"], StoreOption, "Set/replace year"); ap.refer(&mut opt.file) .required() @@ -58,14 +59,52 @@ fn print_tag(tag: &ID3v2) -> io::Result<()> { Ok(()) } +fn modify_tag(tag: &mut ID3v2, new_frame: Frame) -> io::Result<()> { + let mut indices = Vec::new(); + for (i, frame) in tag.frames.iter().enumerate() { + if frame.get_id() == new_frame.id() { + indices.push(i); + } + } + + match indices.len() { + 0 => { + tag.frames.push(new_frame.to_raw()?); + } + + 1 => { + tag.frames[indices[0]] = new_frame.to_raw()?; + } + + _ => { + return Err(format!("Multiple frames of type {} found", new_frame.id()).ioerr()); + } + } + + Ok(()) +} + fn main() -> io::Result<()> { let options = parse_options(); - let tag = ID3v2::from_stream(&mut File::open(options.file)?)?; + let mut tag = ID3v2::from_stream(&mut File::open(options.file)?)?; // println!("{:?}", tag); - // TODO: apply changes from options here - // Use RawFrame::map_string + if options.latin1_as_utf8 { + for frame in &mut tag.frames { + if let Some(new_frame) = + frame.map_string(|s| encoding::from_utf8_mistaken_as_latin1(&s) + .expect("String cannot be encoded in ID3v2 (outside of Unicode BMP)"))? { + *frame = new_frame; + } + } + } + + if let Some(s) = options.set_tags.album { modify_tag(&mut tag, Frame::TALB(s))?; } + if let Some(s) = options.set_tags.artist { modify_tag(&mut tag, Frame::TPE1(s))?; } + if let Some(s) = options.set_tags.title { modify_tag(&mut tag, Frame::TIT2(s))?; } + if let Some(s) = options.set_tags.track { modify_tag(&mut tag, Frame::TRCK(s))?; } + if let Some(s) = options.set_tags.year { modify_tag(&mut tag, Frame::TYER(s))?; } print_tag(&tag)?; |