Skip to main content

ass_core/plugin/sections/aegisub/
processors.rs

1//! Section processor implementations for Aegisub-specific sections.
2//!
3//! Contains [`AegisubProjectProcessor`] and [`AegisubExtradataProcessor`],
4//! which validate `[Aegisub Project]` and `[Aegisub Extradata]` sections
5//! that extend the standard ASS format.
6
7use crate::plugin::{SectionProcessor, SectionResult};
8use alloc::string::String;
9
10/// Handler for Aegisub Project section
11///
12/// Processes `[Aegisub Project]` sections containing project-specific metadata
13/// such as active line tracking, scroll position, and editor state.
14pub struct AegisubProjectProcessor;
15
16impl SectionProcessor for AegisubProjectProcessor {
17    fn name(&self) -> &'static str {
18        "Aegisub Project"
19    }
20
21    fn process(&self, header: &str, lines: &[&str]) -> SectionResult {
22        if !header.eq_ignore_ascii_case("Aegisub Project") {
23            return SectionResult::Ignored;
24        }
25
26        // Validate Aegisub project format
27        for line in lines {
28            let line = line.trim();
29            if line.is_empty() || line.starts_with('!') {
30                continue;
31            }
32
33            // Aegisub project lines should be in key=value or key: value format
34            if !line.contains('=') && !line.contains(':') {
35                return SectionResult::Failed(String::from(
36                    "Invalid Aegisub project line format (expected key=value or key: value)",
37                ));
38            }
39        }
40
41        SectionResult::Processed
42    }
43
44    fn validate(&self, header: &str, lines: &[&str]) -> bool {
45        header.eq_ignore_ascii_case("Aegisub Project") && !lines.is_empty()
46    }
47}
48
49/// Handler for Aegisub Extradata section
50///
51/// Processes `[Aegisub Extradata]` sections containing additional data storage
52/// for extended functionality beyond standard ASS format.
53pub struct AegisubExtradataProcessor;
54
55impl SectionProcessor for AegisubExtradataProcessor {
56    fn name(&self) -> &'static str {
57        "Aegisub Extradata"
58    }
59
60    fn process(&self, header: &str, lines: &[&str]) -> SectionResult {
61        if !header.eq_ignore_ascii_case("Aegisub Extradata") {
62            return SectionResult::Ignored;
63        }
64
65        // Validate extradata format - typically binary data or key-value pairs
66        for line in lines {
67            let line = line.trim();
68            if line.is_empty() {
69                continue;
70            }
71
72            // Extradata can be various formats, so we're permissive
73            // Just ensure it's not completely malformed
74            if line.len() > 10000 {
75                return SectionResult::Failed(String::from(
76                    "Extradata line exceeds maximum length",
77                ));
78            }
79        }
80
81        SectionResult::Processed
82    }
83
84    fn validate(&self, header: &str, _lines: &[&str]) -> bool {
85        header.eq_ignore_ascii_case("Aegisub Extradata")
86    }
87}