use bitflags::bitflags;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::track_disposition")
)]
pub struct TrackDisposition: u32 {
const DEFAULT = 0x0000_0001;
const DUB = 0x0000_0002;
const ORIGINAL = 0x0000_0004;
const COMMENT = 0x0000_0008;
const LYRICS = 0x0000_0010;
const KARAOKE = 0x0000_0020;
const FORCED = 0x0000_0040;
const HEARING_IMPAIRED = 0x0000_0080;
const VISUAL_IMPAIRED = 0x0000_0100;
const CLEAN_EFFECTS = 0x0000_0200;
const ATTACHED_PIC = 0x0000_0400;
const TIMED_THUMBNAILS = 0x0000_0800;
const NON_DIEGETIC = 0x0000_1000;
const CAPTIONS = 0x0001_0000;
const DESCRIPTIONS = 0x0002_0000;
const METADATA = 0x0004_0000;
const DEPENDENT = 0x0008_0000;
const STILL_IMAGE = 0x0010_0000;
}
}
impl TrackDisposition {
#[inline]
pub const fn new() -> Self {
Self::empty()
}
}
impl Default for TrackDisposition {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl TrackDisposition {
#[inline]
pub const fn to_u32(self) -> u32 {
self.bits()
}
#[inline]
pub const fn from_u32(v: u32) -> Self {
Self::from_bits_retain(v)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_is_empty_and_matches_default() {
assert_eq!(TrackDisposition::new(), TrackDisposition::empty());
assert_eq!(TrackDisposition::default(), TrackDisposition::new());
assert_eq!(TrackDisposition::new().bits(), 0);
}
#[test]
fn bit_values_match_ffmpeg_avformat_h() {
assert_eq!(TrackDisposition::DEFAULT.bits(), 0x0000_0001);
assert_eq!(TrackDisposition::DUB.bits(), 0x0000_0002);
assert_eq!(TrackDisposition::ORIGINAL.bits(), 0x0000_0004);
assert_eq!(TrackDisposition::COMMENT.bits(), 0x0000_0008);
assert_eq!(TrackDisposition::LYRICS.bits(), 0x0000_0010);
assert_eq!(TrackDisposition::KARAOKE.bits(), 0x0000_0020);
assert_eq!(TrackDisposition::FORCED.bits(), 0x0000_0040);
assert_eq!(TrackDisposition::HEARING_IMPAIRED.bits(), 0x0000_0080);
assert_eq!(TrackDisposition::VISUAL_IMPAIRED.bits(), 0x0000_0100);
assert_eq!(TrackDisposition::CLEAN_EFFECTS.bits(), 0x0000_0200);
assert_eq!(TrackDisposition::ATTACHED_PIC.bits(), 0x0000_0400);
assert_eq!(TrackDisposition::TIMED_THUMBNAILS.bits(), 0x0000_0800);
assert_eq!(TrackDisposition::NON_DIEGETIC.bits(), 0x0000_1000);
assert_eq!(TrackDisposition::CAPTIONS.bits(), 0x0001_0000);
assert_eq!(TrackDisposition::DESCRIPTIONS.bits(), 0x0002_0000);
assert_eq!(TrackDisposition::METADATA.bits(), 0x0004_0000);
assert_eq!(TrackDisposition::DEPENDENT.bits(), 0x0008_0000);
assert_eq!(TrackDisposition::STILL_IMAGE.bits(), 0x0010_0000);
}
#[test]
fn round_trip_via_u32_for_known_combinations() {
let cases = [
TrackDisposition::empty(),
TrackDisposition::DEFAULT,
TrackDisposition::FORCED | TrackDisposition::HEARING_IMPAIRED,
TrackDisposition::DEFAULT
| TrackDisposition::DUB
| TrackDisposition::COMMENT
| TrackDisposition::CAPTIONS,
TrackDisposition::all(),
];
for c in cases {
assert_eq!(TrackDisposition::from_u32(c.to_u32()), c);
}
}
#[test]
fn unknown_bits_round_trip_losslessly() {
let bits_with_future = TrackDisposition::DEFAULT.bits() | 0x0400_0000;
let rt = TrackDisposition::from_u32(bits_with_future);
assert_eq!(rt.to_u32(), bits_with_future);
assert!(rt.contains(TrackDisposition::DEFAULT));
}
#[test]
fn from_bits_truncate_drops_unknown_bits() {
let bits_with_future = TrackDisposition::DEFAULT.bits() | 0x0400_0000;
let truncated = TrackDisposition::from_bits_truncate(bits_with_future);
assert_eq!(truncated, TrackDisposition::DEFAULT);
assert_eq!(truncated.bits(), 0x0000_0001);
}
#[test]
fn contains_insert_remove_smoke() {
let mut d = TrackDisposition::empty();
assert!(!d.contains(TrackDisposition::DEFAULT));
d.insert(TrackDisposition::DEFAULT | TrackDisposition::FORCED);
assert!(d.contains(TrackDisposition::DEFAULT));
assert!(d.contains(TrackDisposition::FORCED));
d.remove(TrackDisposition::DEFAULT);
assert!(!d.contains(TrackDisposition::DEFAULT));
assert!(d.contains(TrackDisposition::FORCED));
}
}