Skip to content

Commit a164768

Browse files
committed
EBML: Basic MatroskaTag manipulation
1 parent 330a88e commit a164768

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

lofty/src/ebml/tag/generic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! NOTE: We can **ONLY** convert `SimpleTags` that come from a target with **NO** uids
44
55
use super::{Language, MatroskaTag, SimpleTag, TOMBSTONE_SIMPLE_TAG, TargetType};
6-
use crate::tag::items::Lang;
6+
use crate::tag::items::{Lang, UNKNOWN_LANGUAGE};
77
use crate::tag::{ItemKey, ItemValue, Tag, TagItem, TagType};
88

99
use std::borrow::Cow;
@@ -235,7 +235,7 @@ pub(super) fn simple_tag_for_item(
235235
};
236236

237237
// Matroska uses "und" for unknown languages
238-
if lang == *b"XXX" {
238+
if lang == UNKNOWN_LANGUAGE {
239239
lang = *b"und";
240240
}
241241

lofty/src/ebml/tag/mod.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ use std::ops::Deref;
3030
use lofty_attr::tag;
3131

3232
macro_rules! impl_accessor {
33-
($($method:ident => ($target:ident, $name:literal)),+ $(,)?) => {
33+
($($method:ident => ($target:ident, $name:expr)),+ $(,)?) => {
3434
paste::paste! {
3535
$(
3636
fn $method(&self) -> Option<Cow<'_, str>> {
37-
self.get_str(MatroskaTagKey(TargetType::$target, Cow::Borrowed($name)))
37+
self.get_str(MatroskaTagKey(TargetType::$target, $name.into()))
3838
}
3939

4040
fn [<set_ $method>](&mut self, value: String) {
41-
todo!()
41+
self.push(TargetType::$target, SimpleTag::new(Into::<Cow<'_, str>>::into($name), value))
4242
}
4343

4444
fn [<remove_ $method>](&mut self) {
@@ -116,6 +116,43 @@ impl MatroskaTag {
116116
simple_tag.get_str().map(Cow::from)
117117
}
118118

119+
/// Append a new [`SimpleTag`] for the given [`TargetType`]
120+
///
121+
/// NOTE: This will **not** remove other items with the same key.
122+
///
123+
/// # Examples
124+
///
125+
/// ```rust
126+
/// use lofty::ebml::{SimpleTag, TagName, TargetType, MatroskaTag, Language};
127+
/// use lofty::picture::Picture;
128+
/// use lofty::tag::TagExt;
129+
/// use lofty::tag::Accessor;
130+
///
131+
/// # fn main() -> lofty::error::Result<()> {
132+
/// let mut tag = MatroskaTag::default();
133+
///
134+
/// // Set the track title the manual way
135+
/// let title = SimpleTag::new(TagName::Title, "Foo title");
136+
/// tag.push(TargetType::Track, title);
137+
///
138+
/// // Push a Spanish variant of the title
139+
/// let mut title2 = SimpleTag::new(TagName::Title, "Título foo");
140+
/// title2.language = Language::Iso639_2(String::from("spa"));
141+
///
142+
/// tag.push(TargetType::Track, title2);
143+
///
144+
/// // The variant with an undefined language was first in the list
145+
/// assert_eq!(tag.title().as_deref(), Some("Foo title"));
146+
///
147+
/// // And the Spanish variant exists in the tag for players that support it
148+
/// assert_eq!(tag.len(), 2);
149+
/// # Ok(()) }
150+
pub fn push(&mut self, target: TargetType, value: SimpleTag<'_>) {
151+
let value = value.into_owned();
152+
let tag = self.get_or_insert_tag_for_type(target);
153+
tag.simple_tags.push(value);
154+
}
155+
119156
/// Returns all [`Tag`]s, if there are any
120157
pub fn tags(&self) -> impl Iterator<Item = &Tag<'_>> {
121158
self.tags.iter()
@@ -234,10 +271,10 @@ impl MatroskaTag {
234271

235272
impl Accessor for MatroskaTag {
236273
impl_accessor!(
237-
artist => (Track, "ARTIST"),
238-
title => (Track, "TITLE"),
239-
album => (Album, "TITLE"),
240-
comment => (Track, "COMMENT"),
274+
artist => (Track, TagName::Artist),
275+
title => (Track, TagName::Title),
276+
album => (Album, TagName::Title),
277+
comment => (Track, TagName::Comment),
241278
);
242279

243280
fn track(&self) -> Option<u32> {

0 commit comments

Comments
 (0)