mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2025-03-04 06:47:12 +00:00
EBML: add generic conversion to MatroskaTagRef
This commit is contained in:
parent
d99f902344
commit
84bbc4561a
6 changed files with 58 additions and 42 deletions
|
@ -6,6 +6,7 @@ use super::{Language, MatroskaTag, SimpleTag, TargetType, TOMBSTONE_SIMPLE_TAG};
|
|||
use crate::tag::items::Lang;
|
||||
use crate::tag::{ItemKey, ItemValue, Tag, TagItem, TagType};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
|
@ -203,7 +204,7 @@ fn split_simple_tags(
|
|||
|
||||
pub(super) fn merge_tag(tag: Tag, mut matroska_tag: MatroskaTag) -> MatroskaTag {
|
||||
for item in tag.items {
|
||||
let Some((simple_tag, target_type)) = simple_tag_for_item(item) else {
|
||||
let Some((simple_tag, target_type)) = simple_tag_for_item(Cow::Owned(item)) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
@ -215,21 +216,24 @@ pub(super) fn merge_tag(tag: Tag, mut matroska_tag: MatroskaTag) -> MatroskaTag
|
|||
matroska_tag
|
||||
}
|
||||
|
||||
fn simple_tag_for_item(item: TagItem) -> Option<(SimpleTag<'static>, TargetType)> {
|
||||
pub(super) fn simple_tag_for_item(
|
||||
item: Cow<'_, TagItem>,
|
||||
) -> Option<(SimpleTag<'static>, TargetType)> {
|
||||
if !matches!(item.item_value, ItemValue::Text(_) | ItemValue::Locator(_)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (target_type, simple_tag_name) = REVERSE_MAPPINGS.get(&item.item_key).copied()?;
|
||||
|
||||
let TagItem {
|
||||
mut lang,
|
||||
item_key,
|
||||
item_value: ItemValue::Text(text) | ItemValue::Locator(text),
|
||||
..
|
||||
} = item
|
||||
} = item.into_owned()
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let Some((target_type, simple_tag_name)) = REVERSE_MAPPINGS.get(&item_key) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
// Matroska uses "und" for unknown languages
|
||||
if lang == *b"XXX" {
|
||||
lang = *b"und";
|
||||
|
@ -237,8 +241,8 @@ fn simple_tag_for_item(item: TagItem) -> Option<(SimpleTag<'static>, TargetType)
|
|||
|
||||
let lang_str = std::str::from_utf8(lang.as_slice()).unwrap_or("und");
|
||||
|
||||
let mut simple_tag = SimpleTag::new(simple_tag_name.to_string(), text);
|
||||
let mut simple_tag = SimpleTag::new((*simple_tag_name).to_string(), text);
|
||||
simple_tag.language = Language::Iso639_2(lang_str.to_string());
|
||||
|
||||
Some((simple_tag, *target_type))
|
||||
Some((simple_tag, target_type))
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::tag::companion_tag::CompanionTag;
|
|||
use crate::tag::{Accessor, MergeTag, SplitTag, TagExt, TagType};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
use std::ops::Deref;
|
||||
|
||||
|
@ -405,28 +406,36 @@ impl From<crate::tag::Tag> for MatroskaTag {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct MatroskaTagRef<'a, I, S>
|
||||
pub(crate) struct MatroskaTagRef<'a, I>
|
||||
where
|
||||
I: Iterator<Item = TagRef<'a, S>>,
|
||||
S: Iterator<Item = Cow<'a, SimpleTag<'a>>> + 'a,
|
||||
I: Iterator<Item = TagRef<'a>>,
|
||||
{
|
||||
tags: I,
|
||||
pub(crate) tags: I,
|
||||
}
|
||||
|
||||
impl<'a, I, S> From<&'a crate::tag::Tag> for MatroskaTagRef<'a, I, S>
|
||||
where
|
||||
I: Iterator<Item = TagRef<'a, S>>,
|
||||
S: Iterator<Item = Cow<'a, SimpleTag<'a>>>,
|
||||
{
|
||||
fn from(_tag: &'a crate::tag::Tag) -> Self {
|
||||
todo!()
|
||||
pub(crate) fn simple_tags_for_tag(tag: &crate::tag::Tag) -> impl Iterator<Item = TagRef<'static>> {
|
||||
let mut mapped_tags: HashMap<TargetType, Vec<Cow<'static, SimpleTag<'static>>>> =
|
||||
HashMap::new();
|
||||
for item in &tag.items {
|
||||
if let Some((simple_tag, target_type)) = generic::simple_tag_for_item(Cow::Borrowed(item)) {
|
||||
mapped_tags
|
||||
.entry(target_type)
|
||||
.or_default()
|
||||
.push(Cow::Owned(simple_tag))
|
||||
}
|
||||
}
|
||||
|
||||
mapped_tags
|
||||
.into_iter()
|
||||
.map(|(target_type, simple_tags)| TagRef {
|
||||
targets: TargetDescriptor::Basic(target_type),
|
||||
simple_tags: Box::new(simple_tags.into_iter()),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a, I, S> MatroskaTagRef<'a, I, S>
|
||||
impl<'a, I> MatroskaTagRef<'a, I>
|
||||
where
|
||||
I: Iterator<Item = TagRef<'a, S>>,
|
||||
S: Iterator<Item = Cow<'a, SimpleTag<'a>>>,
|
||||
I: Iterator<Item = TagRef<'a>>,
|
||||
{
|
||||
pub(crate) fn write_to<F>(&mut self, _file: &mut F, _write_options: WriteOptions) -> Result<()>
|
||||
where
|
||||
|
@ -434,10 +443,14 @@ where
|
|||
LoftyError: From<<F as Truncate>::Error>,
|
||||
LoftyError: From<<F as Length>::Error>,
|
||||
{
|
||||
todo!()
|
||||
todo!("Writing matroska tags")
|
||||
}
|
||||
|
||||
fn dump_to<W: Write>(&self, _writer: &mut W, _write_options: WriteOptions) -> Result<()> {
|
||||
todo!()
|
||||
pub(crate) fn dump_to<W: Write>(
|
||||
&self,
|
||||
_writer: &mut W,
|
||||
_write_options: WriteOptions,
|
||||
) -> Result<()> {
|
||||
todo!("Dumping matroska tags")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,10 +122,7 @@ impl Tag<'static> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TagRef<'a, I>
|
||||
where
|
||||
I: Iterator<Item = Cow<'a, SimpleTag<'a>>>,
|
||||
{
|
||||
pub(crate) struct TagRef<'a> {
|
||||
pub(crate) targets: TargetDescriptor<'a>,
|
||||
pub(crate) simple_tags: &'a mut I,
|
||||
pub(crate) simple_tags: Box<dyn Iterator<Item = Cow<'a, SimpleTag<'a>>>>,
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
use crate::ebml::tag::write::{write_element, ElementWriterCtx, WriteableElement};
|
||||
use crate::ebml::{ElementId, SimpleTag, TagRef};
|
||||
use crate::ebml::{ElementId, TagRef};
|
||||
use crate::io::FileLike;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::io::Cursor;
|
||||
|
||||
impl<'a, I> WriteableElement for TagRef<'a, I>
|
||||
where
|
||||
I: Iterator<Item = Cow<'a, SimpleTag<'a>>>,
|
||||
{
|
||||
impl WriteableElement for TagRef<'_> {
|
||||
const ID: ElementId = ElementId(0x7373);
|
||||
|
||||
fn write_element<F: FileLike>(
|
||||
|
|
|
@ -99,9 +99,10 @@ pub(crate) fn dump_tag<W: Write>(
|
|||
}
|
||||
}
|
||||
.dump_to(writer, write_options),
|
||||
TagType::Matroska => {
|
||||
todo!("Dump EBML tags")
|
||||
},
|
||||
TagType::Matroska => ebml::tag::MatroskaTagRef {
|
||||
tags: ebml::tag::simple_tags_for_tag(tag),
|
||||
}
|
||||
.dump_to(writer, write_options),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,12 @@ pub(crate) fn init_write_lookup(
|
|||
.write_to(file, write_options)
|
||||
});
|
||||
|
||||
insert!(map, Matroska, { todo!("Generated Matroska tag writer") });
|
||||
insert!(map, Matroska, {
|
||||
lofty::ebml::tag::MatroskaTagRef {
|
||||
tags: lofty::ebml::tag::simple_tags_for_tag(tag),
|
||||
}
|
||||
.write_to(file, write_options)
|
||||
});
|
||||
|
||||
insert!(map, Id3v1, {
|
||||
Into::<lofty::id3::v1::tag::Id3v1TagRef<'_>>::into(tag).write_to(file, write_options)
|
||||
|
|
Loading…
Add table
Reference in a new issue