mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-13 22:22:31 +00:00
mp4: More robust parsing and updated mapping of rtng
atom
This commit is contained in:
parent
100b7e21b1
commit
06b3b6dbaf
2 changed files with 30 additions and 21 deletions
|
@ -216,14 +216,22 @@ pub enum AtomData {
|
|||
}
|
||||
|
||||
/// The parental advisory rating
|
||||
///
|
||||
/// See also:
|
||||
/// <https://docs.mp3tag.de/mapping/#itunesadvisory>
|
||||
/// <https://exiftool.org/TagNames/QuickTime.html>
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum AdvisoryRating {
|
||||
/// A rating of 0
|
||||
/// *Inoffensive*/*None* (0)
|
||||
Inoffensive,
|
||||
/// A rating of 2
|
||||
Clean,
|
||||
/// A rating of (1 || > 2)
|
||||
/// *Explicit* (1 or 4)
|
||||
///
|
||||
/// In the past Apple used the value 4 for explicit content
|
||||
/// that has later been replaced by 1. Both values are considered
|
||||
/// as valid when reading but only the newer value 1 is written.
|
||||
Explicit,
|
||||
/// *Clean*/*Edited* (2)
|
||||
Clean,
|
||||
}
|
||||
|
||||
impl AdvisoryRating {
|
||||
|
@ -231,18 +239,21 @@ impl AdvisoryRating {
|
|||
pub fn as_u8(&self) -> u8 {
|
||||
match self {
|
||||
AdvisoryRating::Inoffensive => 0,
|
||||
AdvisoryRating::Explicit => 1,
|
||||
AdvisoryRating::Clean => 2,
|
||||
AdvisoryRating::Explicit => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for AdvisoryRating {
|
||||
fn from(input: u8) -> Self {
|
||||
impl TryFrom<u8> for AdvisoryRating {
|
||||
type Error = u8;
|
||||
|
||||
fn try_from(input: u8) -> Result<Self, Self::Error> {
|
||||
match input {
|
||||
0 => Self::Inoffensive,
|
||||
2 => Self::Clean,
|
||||
_ => Self::Explicit,
|
||||
0 => Ok(Self::Inoffensive),
|
||||
1 | 4 => Ok(Self::Explicit),
|
||||
2 => Ok(Self::Clean),
|
||||
value => Err(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,17 +152,15 @@ impl Ilst {
|
|||
|
||||
/// Returns the parental advisory rating according to the `rtng` atom
|
||||
pub fn advisory_rating(&self) -> Option<AdvisoryRating> {
|
||||
if let Some(atom) = self.atom(&ADVISORY_RATING) {
|
||||
let rating = match atom.data().next() {
|
||||
Some(AtomData::SignedInteger(si)) => *si as u8,
|
||||
Some(AtomData::Unknown { data: c, .. }) if !c.is_empty() => c[0],
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
return Some(AdvisoryRating::from(rating));
|
||||
}
|
||||
|
||||
None
|
||||
self.atom(&ADVISORY_RATING)
|
||||
.into_iter()
|
||||
.flat_map(Atom::data)
|
||||
.filter_map(|data| match data {
|
||||
AtomData::SignedInteger(si) => u8::try_from(*si).ok(),
|
||||
AtomData::Unknown { data, .. } => data.first().copied(),
|
||||
_ => None,
|
||||
})
|
||||
.find_map(|rating| AdvisoryRating::try_from(rating).ok())
|
||||
}
|
||||
|
||||
/// Sets the advisory rating
|
||||
|
|
Loading…
Reference in a new issue