use crate::quality::{Quality, QualitySource};
const ALL: &[(Quality, QualitySource, u32)] = &[
(Quality::Unknown, QualitySource::Unknown, 0),
(Quality::Sdtv, QualitySource::Television, 480),
(Quality::Dvd, QualitySource::Dvd, 480),
(Quality::Webrip480p, QualitySource::WebRip, 480),
(Quality::Webdl480p, QualitySource::Web, 480),
(Quality::Bluray480p, QualitySource::Bluray, 480),
(Quality::Bluray576p, QualitySource::Bluray, 576),
(Quality::Hdtv720p, QualitySource::Television, 720),
(Quality::Webrip720p, QualitySource::WebRip, 720),
(Quality::Webdl720p, QualitySource::Web, 720),
(Quality::Bluray720p, QualitySource::Bluray, 720),
(Quality::Bluray1080p, QualitySource::Bluray, 1080),
(Quality::Hdtv1080p, QualitySource::Television, 1080),
(Quality::Webrip1080p, QualitySource::WebRip, 1080),
(Quality::Webdl1080p, QualitySource::Web, 1080),
(Quality::RawHd, QualitySource::TelevisionRaw, 1080),
(Quality::Hdtv2160p, QualitySource::Television, 2160),
(Quality::Webrip2160p, QualitySource::WebRip, 2160),
(Quality::Webdl2160p, QualitySource::Web, 2160),
(Quality::Bluray2160p, QualitySource::Bluray, 2160),
(Quality::Bluray1080pRemux, QualitySource::BlurayRaw, 1080),
(Quality::Bluray2160pRemux, QualitySource::BlurayRaw, 2160),
];
fn source_rank(s: QualitySource) -> u8 {
match s {
QualitySource::Unknown => 0,
QualitySource::Television => 1,
QualitySource::TelevisionRaw => 2,
QualitySource::Web => 3,
QualitySource::WebRip => 4,
QualitySource::Dvd => 5,
QualitySource::Bluray => 6,
QualitySource::BlurayRaw => 7,
}
}
pub(crate) fn find_by_source_and_resolution(source: QualitySource, pixels: u32) -> Quality {
for (q, s, r) in ALL {
if *s == source && *r == pixels {
return *q;
}
}
if pixels < 720 {
match source {
QualitySource::Television => return Quality::Sdtv,
QualitySource::Web => return Quality::Webdl480p,
QualitySource::WebRip => return Quality::Webrip480p,
_ => {}
}
}
let target_rank = source_rank(source);
ALL.iter()
.filter(|(_, _, r)| *r == pixels)
.filter(|(_, s, _)| source_rank(*s) >= target_rank)
.min_by_key(|(_, s, _)| source_rank(*s))
.map(|(q, _, _)| *q)
.unwrap_or(Quality::Unknown)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::quality::{Quality, QualitySource};
#[test]
fn finds_webdl_1080p_by_source_and_resolution() {
let q = find_by_source_and_resolution(QualitySource::Web, 1080);
assert_eq!(q, Quality::Webdl1080p);
}
#[test]
fn finds_hdtv_720p_by_source_and_resolution() {
let q = find_by_source_and_resolution(QualitySource::Television, 720);
assert_eq!(q, Quality::Hdtv720p);
}
#[test]
fn unknown_for_unmapped_combo() {
let q = find_by_source_and_resolution(QualitySource::Unknown, 9999);
assert_eq!(q, Quality::Unknown);
}
#[test]
fn television_zero_pixels_falls_back_to_sdtv() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Television, 0),
Quality::Sdtv
);
}
#[test]
fn television_576_falls_back_to_sdtv() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Television, 576),
Quality::Sdtv
);
}
#[test]
fn web_576_falls_back_to_webdl480p() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Web, 576),
Quality::Webdl480p
);
}
#[test]
fn webrip_zero_pixels_falls_back_to_webrip480p() {
assert_eq!(
find_by_source_and_resolution(QualitySource::WebRip, 0),
Quality::Webrip480p
);
}
#[test]
fn television_raw_at_1080_is_rawhd() {
assert_eq!(
find_by_source_and_resolution(QualitySource::TelevisionRaw, 1080),
Quality::RawHd
);
}
#[test]
fn television_raw_at_720_promotes_to_webdl720p() {
assert_eq!(
find_by_source_and_resolution(QualitySource::TelevisionRaw, 720),
Quality::Webdl720p
);
}
#[test]
fn bluray_raw_at_720_is_unknown() {
assert_eq!(
find_by_source_and_resolution(QualitySource::BlurayRaw, 720),
Quality::Unknown
);
}
#[test]
fn bluray_576_exact_match() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Bluray, 576),
Quality::Bluray576p
);
}
#[test]
fn dvd_at_720_promotes_to_bluray720p() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Dvd, 720),
Quality::Bluray720p
);
}
#[test]
fn bluray_540_is_unknown() {
assert_eq!(
find_by_source_and_resolution(QualitySource::Bluray, 540),
Quality::Unknown
);
}
#[test]
fn source_rank_matches_csharp_ordinals() {
assert_eq!(source_rank(QualitySource::Unknown), 0);
assert_eq!(source_rank(QualitySource::Television), 1);
assert_eq!(source_rank(QualitySource::TelevisionRaw), 2);
assert_eq!(source_rank(QualitySource::Web), 3);
assert_eq!(source_rank(QualitySource::WebRip), 4);
assert_eq!(source_rank(QualitySource::Dvd), 5);
assert_eq!(source_rank(QualitySource::Bluray), 6);
assert_eq!(source_rank(QualitySource::BlurayRaw), 7);
}
}