1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
/// Options to control how Lofty writes to a file
///
/// This acts as a dumping ground for all sorts of format-specific settings. As such, this is best
/// used as an application global config that gets set once.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct WriteOptions {
pub(crate) preferred_padding: Option<u32>,
pub(crate) remove_others: bool,
pub(crate) respect_read_only: bool,
pub(crate) uppercase_id3v2_chunk: bool,
pub(crate) use_id3v23: bool,
}
impl WriteOptions {
/// Default preferred padding size in bytes
pub const DEFAULT_PREFERRED_PADDING: u32 = 1024;
/// Creates a new `WriteOptions`, alias for `Default` implementation
///
/// See also: [`WriteOptions::default`]
///
/// # Examples
///
/// ```rust
/// use lofty::config::WriteOptions;
///
/// let write_options = WriteOptions::new();
/// ```
pub const fn new() -> Self {
Self {
preferred_padding: Some(Self::DEFAULT_PREFERRED_PADDING),
remove_others: false,
respect_read_only: true,
uppercase_id3v2_chunk: true,
use_id3v23: false,
}
}
/// Set the preferred padding size in bytes
///
/// If the tag format being written supports padding, this will be the size of the padding
/// in bytes.
///
/// NOTES:
///
/// * Not all tag formats support padding
/// * The actual padding size may be different from this value, depending on tag size limitations
///
/// # Examples
///
/// ```rust
/// use lofty::config::WriteOptions;
///
/// // I really don't want my files rewritten, so I'll double the padding size!
/// let options = WriteOptions::new().preferred_padding(2048);
///
/// // ...Or I don't want padding under any circumstances!
/// let options = WriteOptions::new().preferred_padding(0);
/// ```
pub fn preferred_padding(mut self, preferred_padding: u32) -> Self {
match preferred_padding {
0 => self.preferred_padding = None,
_ => self.preferred_padding = Some(preferred_padding),
}
self
}
/// Whether to remove all other tags when writing
///
/// If set to `true`, only the tag being written will be kept in the file.
///
/// # Examples
///
/// ```rust,no_run
/// use lofty::config::WriteOptions;
/// use lofty::prelude::*;
/// use lofty::tag::{Tag, TagType};
///
/// # fn main() -> lofty::error::Result<()> {
/// let mut id3v2_tag = Tag::new(TagType::Id3v2);
///
/// // ...
///
/// // I only want to keep the ID3v2 tag around!
/// let options = WriteOptions::new().remove_others(true);
/// id3v2_tag.save_to_path("test.mp3", options)?;
/// # Ok(()) }
/// ```
pub fn remove_others(mut self, remove_others: bool) -> Self {
self.remove_others = remove_others;
self
}
/// Whether to respect read-only tag items
///
/// Some tag formats allow for items to be marked as read-only. If set to `true`, these items
/// will take priority over newly created tag items.
///
/// NOTE: In the case of APE tags, one can mark the entire tag as read-only. This will append
/// the existing tag items to the new tag.
///
/// # Examples
///
/// ```rust,no_run
/// use lofty::config::WriteOptions;
/// use lofty::prelude::*;
/// use lofty::tag::{Tag, TagType};
///
/// # fn main() -> lofty::error::Result<()> {
/// let mut id3v2_tag = Tag::new(TagType::Id3v2);
///
/// // ...
///
/// // I don't care about read-only items, I want to write my new items!
/// let options = WriteOptions::new().respect_read_only(false);
/// id3v2_tag.save_to_path("test.mp3", options)?;
/// # Ok(()) }
/// ```
pub fn respect_read_only(mut self, respect_read_only: bool) -> Self {
self.respect_read_only = respect_read_only;
self
}
/// Whether to uppercase the ID3v2 chunk name
///
/// When dealing with RIFF/AIFF files, some software may expect the ID3v2 chunk name to be
/// lowercase.
///
/// NOTE: The vast majority of software will be able to read both upper and lowercase
/// chunk names.
///
/// # Examples
///
/// ```rust,no_run
/// use lofty::config::WriteOptions;
/// use lofty::prelude::*;
/// use lofty::tag::{Tag, TagType};
///
/// # fn main() -> lofty::error::Result<()> {
/// let mut id3v2_tag = Tag::new(TagType::Id3v2);
///
/// // ...
///
/// // I want to keep the ID3v2 chunk name lowercase
/// let options = WriteOptions::new().uppercase_id3v2_chunk(false);
/// id3v2_tag.save_to_path("test.mp3", options)?;
/// # Ok(()) }
pub fn uppercase_id3v2_chunk(mut self, uppercase_id3v2_chunk: bool) -> Self {
self.uppercase_id3v2_chunk = uppercase_id3v2_chunk;
self
}
/// Whether or not to use ID3v2.3 when saving [`TagType::Id3v2`](crate::tag::TagType::Id3v2)
/// or [`Id3v2Tag`](crate::id3::v2::Id3v2Tag)
///
/// By default, Lofty will save ID3v2.4 tags. This option allows you to save ID3v2.3 tags instead.
///
/// # Examples
///
/// ```rust,no_run
/// use lofty::config::WriteOptions;
/// use lofty::prelude::*;
/// use lofty::tag::{Tag, TagType};
///
/// # fn main() -> lofty::error::Result<()> {
/// let mut id3v2_tag = Tag::new(TagType::Id3v2);
///
/// // ...
///
/// // I need to save ID3v2.3 tags to support older software
/// let options = WriteOptions::new().use_id3v23(true);
/// id3v2_tag.save_to_path("test.mp3", options)?;
/// # Ok(()) }
/// ```
pub fn use_id3v23(&mut self, use_id3v23: bool) -> Self {
self.use_id3v23 = use_id3v23;
*self
}
}
impl Default for WriteOptions {
/// The default implementation for `WriteOptions`
///
/// The defaults are as follows:
///
/// ```rust,ignore
/// WriteOptions {
/// preferred_padding: 1024,
/// remove_others: false,
/// respect_read_only: true,
/// uppercase_id3v2_chunk: true,
/// use_id3v23: false,
/// }
/// ```
fn default() -> Self {
Self::new()
}
}