lofty-rs icon indicating copy to clipboard operation
lofty-rs copied to clipboard

Add write options

Open Serial-ATA opened this issue 11 months ago • 0 comments

Summary

Just like ParseOptions, there may be some things that a caller wants to configure during a write. These options would be passed to AudioFile::save_to and TagExt::save_to.

Some options I can think of being useful are:

  • preferred_padding: Right now we make use of padding, but in its absence we don't end up adding any. Since this is something multiple tags support, it would be nice to add a specified amount of padding to tags when requested.
  • remove_others: Removing tags from an existing file isn't the easiest process currently. It would be nice if the caller could specify that they want to, for example, remove an APE and ID3v1 tag when they are only attempting to save an ID3v2 tag. There are currently three ways to remove tags:
    • TagExt::remove_from/TagType::remove_from
      • These remove tags one at a time, but that isn't helpful if there a singular preferred tag type to be written, as it would require the caller to remove each tag, as well as seek back to the beginning of the file to then do their write.
    • TagExt::save_to with an empty tag
      • Same issue as above
    • AudioFile::save_to
      • This will handle the seeking, but will not remove any tag field that is None. This means that calling <AudioFile>::remove_<tag> will not remove from a file it is saving to. A workaround for this is to do <AudioFile>::<tag>_mut followed by TagExt::clear, as empty tags will be treated as a removal request.
  • respect_read_only: Some tags allow items to be marked read only, so we should have an option to retain any read only items found in the tags of the file being written to. Read only items are currently (unavoidably) respected in APE tags.

API design

pub struct WriteOptions {
    // Default: 1024, seems like a safe size
    preferred_padding: usize,
    // Default: false, destructive
    remove_others: bool,
    // Default: true, potentially destructive?
    //          Read only items would take priority over newly created tag items.
    respect_read_only: bool,  
    // ...?
}

pub trait TagExt {
    fn save_to(&self, file: &mut File, options: WriteOptions) -> std::result::Result<(), Self::Err>;
}

pub trait AudioFile {
    fn save_to(&self, file: &mut File, options: WriteOptions) -> Result<()>;
}

Serial-ATA avatar Jul 06 '23 20:07 Serial-ATA