pub struct VorbisComment {
pub vendor_string: String,
pub fields: Vec<String>,
}Expand description
A VORBIS_COMMENT metadata block
This block contains metadata such as track name,
artist name, album name, etc. Its contents are
UTF-8 encoded, =-delimited text fields
with a field name followed by value,
such as:
TITLE=Track TitleField names are case-insensitive and may occur multiple times within the same comment (a track may have multiple artists and choose to store an “ARTIST” field for each one).
Commonly-used fields are available in the fields module.
This block may occur only once in a FLAC file.
§Byte Order
Unlike the rest of a FLAC file, the Vorbis comment’s length fields are stored in little-endian byte order.
| Bits | Field | Meaning |
|---|---|---|
| 32 | vendor string len | length of vendor string, in bytes |
vendor string len×8 | vendor_string | vendor string, in UTF-8 |
| 32 | field count | number of vendor string fields |
| 32 | field₀ len | length of field₀, in bytes |
field₀ len×8 | fields₀ | first field value, in UTF-8 |
| 32 | field₁ len | length of field₁, in bytes |
field₁ len×8 | fields₁ | second field value, in UTF-8 |
| ⋮ |
§Example
use bitstream_io::{BitReader, BitRead, LittleEndian};
use flac_codec::metadata::VorbisComment;
use flac_codec::metadata::fields::{TITLE, ALBUM, ARTIST};
let data: &[u8] = &[
0x20, 0x00, 0x00, 0x00, // 32 byte vendor string
0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
0x65, 0x20, 0x6c, 0x69, 0x62, 0x46, 0x4c, 0x41,
0x43, 0x20, 0x31, 0x2e, 0x34, 0x2e, 0x33, 0x20,
0x32, 0x30, 0x32, 0x33, 0x30, 0x36, 0x32, 0x33,
0x02, 0x00, 0x00, 0x00, // 2 fields
0x0d, 0x00, 0x00, 0x00, // 13 byte field 1
0x54, 0x49, 0x54, 0x4c, 0x45, 0x3d, 0x54, 0x65,
0x73, 0x74, 0x69, 0x6e, 0x67,
0x10, 0x00, 0x00, 0x00, // 16 byte field 2
0x41, 0x4c, 0x42, 0x55, 0x4d, 0x3d, 0x54, 0x65,
0x73, 0x74, 0x20, 0x41, 0x6c, 0x62, 0x75, 0x6d,
];
let mut r = BitReader::endian(data, LittleEndian);
let comment = r.parse::<VorbisComment>().unwrap();
assert_eq!(
&comment,
&VorbisComment {
vendor_string: "reference libFLAC 1.4.3 20230623".to_string(),
fields: vec![
"TITLE=Testing".to_string(),
"ALBUM=Test Album".to_string(),
],
},
);
assert_eq!(comment.get(TITLE), Some("Testing"));
assert_eq!(comment.get(ALBUM), Some("Test Album"));
assert_eq!(comment.get(ARTIST), None);Fields§
§vendor_string: StringThe vendor string
fields: Vec<String>The individual metadata comment strings
Implementations§
Source§impl VorbisComment
impl VorbisComment
Sourcepub fn get(&self, field: &str) -> Option<&str>
pub fn get(&self, field: &str) -> Option<&str>
Given a field name, returns first matching value, if any
Fields are matched case-insensitively
§Example
use flac_codec::metadata::{VorbisComment, fields::{ARTIST, TITLE}};
let comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
assert_eq!(comment.get(ARTIST), Some("Artist 1"));
assert_eq!(comment.get(TITLE), None);Sourcepub fn set<S>(&mut self, field: &str, value: S)where
S: Display,
pub fn set<S>(&mut self, field: &str, value: S)where
S: Display,
Replaces any instances of the given field with value
Fields are matched case-insensitively
§Panics
Panics if field contains the = character.
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let mut comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
comment.set(ARTIST, "Artist 3");
assert_eq!(
comment.all(ARTIST).collect::<Vec<_>>(),
vec!["Artist 3"],
);Sourcepub fn all(&self, field: &str) -> impl Iterator<Item = &str>
pub fn all(&self, field: &str) -> impl Iterator<Item = &str>
Given a field name, iterates over any matching values
Fields are matched case-insensitively
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
assert_eq!(
comment.all(ARTIST).collect::<Vec<_>>(),
vec!["Artist 1", "Artist 2"],
);Sourcepub fn insert<S>(&mut self, field: &str, value: S)where
S: Display,
pub fn insert<S>(&mut self, field: &str, value: S)where
S: Display,
Adds new instance of field with the given value
§Panics
Panics if field contains the = character.
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let mut comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
comment.insert(ARTIST, "Artist 3");
assert_eq!(
comment.all(ARTIST).collect::<Vec<_>>(),
vec!["Artist 1", "Artist 2", "Artist 3"],
);Sourcepub fn remove(&mut self, field: &str)
pub fn remove(&mut self, field: &str)
Removes any matching instances of the given field
Fields are matched case-insensitively
§Panics
Panics if field contains the = character.
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let mut comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
comment.remove(ARTIST);
assert_eq!(comment.get(ARTIST), None);Sourcepub fn replace<S: Display>(
&mut self,
field: &str,
replacements: impl IntoIterator<Item = S>,
)
pub fn replace<S: Display>( &mut self, field: &str, replacements: impl IntoIterator<Item = S>, )
Replaces any instances of the given field with the given values
Fields are matched case-insensitively
§Panics
Panics if field contains the = character
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let mut comment = VorbisComment {
fields: vec![
"ARTIST=Artist 1".to_owned(),
"ARTIST=Artist 2".to_owned(),
],
..VorbisComment::default()
};
comment.replace(ARTIST, ["Artist 3", "Artist 4"]);
assert_eq!(
comment.all(ARTIST).collect::<Vec<_>>(),
vec!["Artist 3", "Artist 4"],
);
// reminder that Option also implements IntoIterator
comment.replace(ARTIST, Some("Artist 5"));
assert_eq!(
comment.all(ARTIST).collect::<Vec<_>>(),
vec!["Artist 5"],
);Sourcepub fn replace_with<S: Display>(
&mut self,
field: &str,
f: impl FnMut(&str) -> S,
)
pub fn replace_with<S: Display>( &mut self, field: &str, f: impl FnMut(&str) -> S, )
Replaces instances of the given field with a closure’s result
Closure takes the field’s current value and returns
something Display-able such as a String.
The closure is called for each maching field, if any.
Fields are matched case-insensitively.
§Panics
Panics if field contains the = character
§Example
use flac_codec::metadata::{VorbisComment, fields::ARTIST};
let mut comment = VorbisComment {
fields: vec![
"ARTIST=some artist".to_owned(),
],
..VorbisComment::default()
};
comment.replace_with(ARTIST, |s| s.to_ascii_uppercase());
assert_eq!(comment.get(ARTIST), Some("SOME ARTIST"));Trait Implementations§
Source§impl AsBlockRef for VorbisComment
impl AsBlockRef for VorbisComment
Source§fn as_block_ref(&self) -> BlockRef<'_>
fn as_block_ref(&self) -> BlockRef<'_>
Source§impl Clone for VorbisComment
impl Clone for VorbisComment
Source§fn clone(&self) -> VorbisComment
fn clone(&self) -> VorbisComment
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more