lofty/config/
write_options.rs

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