From 4f848c27f040c7186abc10881c03bdf3d5b5c9e5 Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Sun, 23 Aug 2026 18:12:47 +0100 Subject: [PATCH] fix(parse): close title on spelled-out season ranges --- crates/arr-parse/src/markers.rs | 8 ++++++++ crates/arr-parse/tests/parse.rs | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/crates/arr-parse/src/markers.rs b/crates/arr-parse/src/markers.rs index 4724239..290b63b 100644 --- a/crates/arr-parse/src/markers.rs +++ b/crates/arr-parse/src/markers.rs @@ -55,11 +55,19 @@ pub(crate) fn classify_pair(a: &str, b: &str) -> Option<(Marker, Strength)> { ("season", n) if !n.is_empty() && n.bytes().all(|c| c.is_ascii_digit()) => { (Marker::Junk, Strength::Strong) } + ("seasons", n) if is_season_count(n) => (Marker::Junk, Strength::Strong), _ => return None, }; Some(m) } +/// `1`, `1-3`: the count after a spelled-out `Seasons`. Each part is 1-2 +/// digits so a trailing year (`Four Seasons 2024`) never reads as a count. +fn is_season_count(n: &str) -> bool { + n.split('-') + .all(|part| (1..=2).contains(&part.len()) && part.bytes().all(|b| b.is_ascii_digit())) +} + #[allow(clippy::too_many_lines)] fn classify_exact(t: &str) -> Option<(Marker, Strength)> { use Strength::{Strong, Weak}; diff --git a/crates/arr-parse/tests/parse.rs b/crates/arr-parse/tests/parse.rs index 1be678f..1ed0adc 100644 --- a/crates/arr-parse/tests/parse.rs +++ b/crates/arr-parse/tests/parse.rs @@ -343,6 +343,42 @@ fn cases() -> Vec { ..NameClaims::default() }, }, + Case { + // The spelled-out plural range closes the title too. + name: "Fallout.Seasons.1-3.1080p.BluRay-GROUP", + want: NameClaims { + title: s("Fallout"), + resolution: Some(Resolution::P1080), + source: Some(Source::BluRay), + group: s("GROUP"), + episode: Some(EpisodeClaim::Seasons { first: 1, last: 3 }), + ..NameClaims::default() + }, + }, + Case { + // A bare number after the plural is a single season, like + // the singular form. + name: "Show.Name.Seasons.1.1080p.WEB-DL-GROUP", + want: NameClaims { + title: s("Show Name"), + resolution: Some(Resolution::P1080), + source: Some(Source::WebDl), + group: s("GROUP"), + episode: Some(EpisodeClaim::Season { season: 1 }), + ..NameClaims::default() + }, + }, + Case { + // A year-sized number after `Seasons` is a year, not a count. + name: "The.Four.Seasons.2024.1080p.WEB-DL", + want: NameClaims { + title: s("The Four Seasons"), + year: Some(2024), + resolution: Some(Resolution::P1080), + source: Some(Source::WebDl), + ..NameClaims::default() + }, + }, Case { name: "Movie.2019.4K.HDR.DV.2160p.BDRemux.Ita.Eng.x265-NAHOM", want: NameClaims {