use crate::bytes;
const UHD_INDEX_VERSION: &str = "INDX0300";
const INDEX_TAG: &[u8; 4] = b"INDX";
#[must_use]
pub fn has_index_tag(index: &[u8]) -> bool {
index.get(0..4) == Some(INDEX_TAG.as_slice())
}
#[must_use]
pub fn read_index_version(index: &[u8]) -> Option<String> {
bytes::read_ascii(index, 0, 8)
}
#[must_use]
pub fn is_uhd(index: &[u8]) -> bool {
read_index_version(index).as_deref() == Some(UHD_INDEX_VERSION)
}
#[cfg(test)]
mod tests {
use proptest::prelude::{any, prop_assert, prop_assert_eq, proptest};
use super::{has_index_tag, is_uhd, read_index_version};
#[test]
fn uhd_magic_is_detected() {
let buf = *b"INDX0300\x00\x01\x02\x03";
assert!(is_uhd(&buf));
assert_eq!(read_index_version(&buf).as_deref(), Some("INDX0300"));
}
#[test]
fn exact_eight_byte_magic_is_detected() {
assert!(is_uhd(b"INDX0300"));
assert_eq!(read_index_version(b"INDX0300").as_deref(), Some("INDX0300"));
}
#[test]
fn regular_bluray_is_not_uhd() {
let buf = *b"INDX0200\x00\x00";
assert!(!is_uhd(&buf));
assert_eq!(read_index_version(&buf).as_deref(), Some("INDX0200"));
}
#[test]
fn short_or_empty_buffer_is_not_uhd() {
assert!(!is_uhd(b"INDX030"));
assert_eq!(read_index_version(b"INDX030"), None);
assert!(!is_uhd(b""));
assert_eq!(read_index_version(b""), None);
}
#[test]
fn index_tag_is_detected_independently_of_the_version() {
assert!(has_index_tag(b"INDX0200"));
assert!(has_index_tag(b"INDX0300"));
assert!(has_index_tag(b"INDX9999"));
assert!(has_index_tag(b"INDX")); assert!(!has_index_tag(b"XXXXjunk"));
assert!(!has_index_tag(b"IND")); assert!(!has_index_tag(b""));
}
proptest! {
#[test]
fn is_uhd_iff_first_eight_bytes_are_the_magic(buf in any::<Vec<u8>>()) {
let expected = buf.get(0..8) == Some(b"INDX0300".as_slice());
prop_assert_eq!(is_uhd(&buf), expected);
}
#[test]
fn magic_prefix_is_always_uhd(suffix in any::<Vec<u8>>()) {
let mut buf = b"INDX0300".to_vec();
buf.extend_from_slice(&suffix);
prop_assert!(is_uhd(&buf));
let version = read_index_version(&buf);
prop_assert_eq!(version.as_deref(), Some("INDX0300"));
}
}
}