ass_core/parser/sections/styles/
parse_line.rs1use super::StylesParser;
7use crate::parser::{
8 ast::{Span, Style},
9 errors::ParseError,
10};
11use alloc::vec::Vec;
12
13impl<'a> StylesParser<'a> {
14 pub fn parse_style_line(
33 line: &'a str,
34 format: &[&'a str],
35 line_number: u32,
36 ) -> core::result::Result<Style<'a>, ParseError> {
37 let (adjusted_line, parent_style) = if line.trim_start().starts_with('*') {
39 line.find(',').map_or((line, None), |first_comma| {
41 let parent_part = &line[0..first_comma];
42 let parent_name = parent_part.trim_start().trim_start_matches('*').trim();
43 let remaining = &line[first_comma + 1..];
44 (remaining, Some(parent_name))
45 })
46 } else {
47 (line, None)
48 };
49
50 let parts: Vec<&str> = adjusted_line.split(',').collect();
51
52 let format = if format.is_empty() {
53 &[
54 "Name",
55 "Fontname",
56 "Fontsize",
57 "PrimaryColour",
58 "SecondaryColour",
59 "OutlineColour",
60 "BackColour",
61 "Bold",
62 "Italic",
63 "Underline",
64 "StrikeOut",
65 "ScaleX",
66 "ScaleY",
67 "Spacing",
68 "Angle",
69 "BorderStyle",
70 "Outline",
71 "Shadow",
72 "Alignment",
73 "MarginL",
74 "MarginR",
75 "MarginV",
76 "Encoding",
77 ]
78 } else {
79 format
80 };
81
82 if parts.len() < format.len() {
83 return Err(ParseError::InsufficientFields {
84 expected: format.len(),
85 found: parts.len(),
86 line: line_number as usize,
87 });
88 }
89
90 let get_field = |name: &str| -> &'a str {
91 format
92 .iter()
93 .position(|&field| field.eq_ignore_ascii_case(name))
94 .and_then(|idx| parts.get(idx))
95 .map_or("", |s| s.trim())
96 };
97
98 let span = Span::new(0, 0, line_number, 1);
100
101 Ok(Style {
102 name: get_field("Name"),
103 parent: parent_style,
104 fontname: get_field("Fontname"),
105 fontsize: get_field("Fontsize"),
106 primary_colour: get_field("PrimaryColour"),
107 secondary_colour: get_field("SecondaryColour"),
108 outline_colour: get_field("OutlineColour"),
109 back_colour: get_field("BackColour"),
110 bold: get_field("Bold"),
111 italic: get_field("Italic"),
112 underline: get_field("Underline"),
113 strikeout: get_field("StrikeOut"),
114 scale_x: get_field("ScaleX"),
115 scale_y: get_field("ScaleY"),
116 spacing: get_field("Spacing"),
117 angle: get_field("Angle"),
118 border_style: get_field("BorderStyle"),
119 outline: get_field("Outline"),
120 shadow: get_field("Shadow"),
121 alignment: get_field("Alignment"),
122 margin_l: get_field("MarginL"),
123 margin_r: get_field("MarginR"),
124 margin_v: get_field("MarginV"),
125 margin_t: format
126 .iter()
127 .any(|&f| f.eq_ignore_ascii_case("MarginT"))
128 .then(|| get_field("MarginT")),
129 margin_b: format
130 .iter()
131 .any(|&f| f.eq_ignore_ascii_case("MarginB"))
132 .then(|| get_field("MarginB")),
133 encoding: get_field("Encoding"),
134 relative_to: format
135 .iter()
136 .any(|&f| f.eq_ignore_ascii_case("RelativeTo"))
137 .then(|| get_field("RelativeTo")),
138 span,
139 })
140 }
141}