Skip to main content

ass_editor/core/builders/
style_build.rs

1//! Default style-line serialization for [`StyleBuilder`].
2
3use super::StyleBuilder;
4use crate::core::errors::Result;
5use ass_core::ScriptVersion;
6
7#[cfg(not(feature = "std"))]
8use alloc::{
9    format,
10    string::{String, ToString},
11    vec,
12};
13
14impl StyleBuilder {
15    /// Build the style (validates required fields)
16    pub fn build(self) -> Result<String> {
17        let name = self.name.unwrap_or_else(|| "NewStyle".to_string());
18        let fontname = self.fontname.unwrap_or_else(|| "Arial".to_string());
19        let fontsize = self.fontsize.unwrap_or(20);
20        let primary_colour = self
21            .primary_colour
22            .unwrap_or_else(|| "&Hffffff".to_string());
23        let secondary_colour = self
24            .secondary_colour
25            .unwrap_or_else(|| "&Hff0000".to_string());
26        let outline_colour = self.outline_colour.unwrap_or_else(|| "&H0".to_string());
27        let back_colour = self.back_colour.unwrap_or_else(|| "&H0".to_string());
28        let bold = if self.bold.unwrap_or(false) {
29            "-1"
30        } else {
31            "0"
32        };
33        let italic = if self.italic.unwrap_or(false) {
34            "-1"
35        } else {
36            "0"
37        };
38        let underline = if self.underline.unwrap_or(false) {
39            "-1"
40        } else {
41            "0"
42        };
43        let strikeout = if self.strikeout.unwrap_or(false) {
44            "-1"
45        } else {
46            "0"
47        };
48        let scale_x = self.scale_x.unwrap_or(100.0);
49        let scale_y = self.scale_y.unwrap_or(100.0);
50        let spacing = self.spacing.unwrap_or(0.0);
51        let angle = self.angle.unwrap_or(0.0);
52        let border_style = self.border_style.unwrap_or(1);
53        let outline = self.outline.unwrap_or(2.0);
54        let shadow = self.shadow.unwrap_or(0.0);
55        let alignment = self.alignment.unwrap_or(2);
56        let margin_l = self.margin_l.unwrap_or(10);
57        let margin_r = self.margin_r.unwrap_or(10);
58        let margin_v = self.margin_v.unwrap_or(10);
59        let encoding = self.encoding.unwrap_or(1);
60
61        // Handle V4++ fields - margin_t/margin_b override margin_v when present
62        // relative_to is also a V4++ field
63        // Note: The actual format line would determine the field order and presence
64        // For now, we use the standard V4+ format
65
66        // Format as ASS style line
67        let line = format!(
68            "Style: {name},{fontname},{fontsize},{primary_colour},{secondary_colour},{outline_colour},{back_colour},{bold},{italic},{underline},{strikeout},{scale_x},{scale_y},{spacing},{angle},{border_style},{outline},{shadow},{alignment},{margin_l},{margin_r},{margin_v},{encoding}"
69        );
70
71        Ok(line)
72    }
73
74    /// Build the style with a specific version format
75    pub fn build_with_version(self, version: ScriptVersion) -> Result<String> {
76        // Define format based on version
77        let format = match version {
78            ScriptVersion::SsaV4 => {
79                // SSA v4 has fewer fields
80                vec![
81                    "Name",
82                    "Fontname",
83                    "Fontsize",
84                    "PrimaryColour",
85                    "SecondaryColour",
86                    "TertiaryColour",
87                    "BackColour",
88                    "Bold",
89                    "Italic",
90                    "BorderStyle",
91                    "Outline",
92                    "Shadow",
93                    "Alignment",
94                    "MarginL",
95                    "MarginR",
96                    "MarginV",
97                    "AlphaLevel",
98                    "Encoding",
99                ]
100            }
101            ScriptVersion::AssV4 => {
102                // Standard ASS v4 format
103                vec![
104                    "Name",
105                    "Fontname",
106                    "Fontsize",
107                    "PrimaryColour",
108                    "SecondaryColour",
109                    "OutlineColour",
110                    "BackColour",
111                    "Bold",
112                    "Italic",
113                    "Underline",
114                    "StrikeOut",
115                    "ScaleX",
116                    "ScaleY",
117                    "Spacing",
118                    "Angle",
119                    "BorderStyle",
120                    "Outline",
121                    "Shadow",
122                    "Alignment",
123                    "MarginL",
124                    "MarginR",
125                    "MarginV",
126                    "Encoding",
127                ]
128            }
129            ScriptVersion::AssV4Plus => {
130                // ASS v4++ format with additional fields
131                vec![
132                    "Name",
133                    "Fontname",
134                    "Fontsize",
135                    "PrimaryColour",
136                    "SecondaryColour",
137                    "OutlineColour",
138                    "BackColour",
139                    "Bold",
140                    "Italic",
141                    "Underline",
142                    "StrikeOut",
143                    "ScaleX",
144                    "ScaleY",
145                    "Spacing",
146                    "Angle",
147                    "BorderStyle",
148                    "Outline",
149                    "Shadow",
150                    "Alignment",
151                    "MarginL",
152                    "MarginR",
153                    "MarginV",
154                    "MarginT",
155                    "MarginB",
156                    "Encoding",
157                    "RelativeTo",
158                ]
159            }
160        };
161
162        self.build_with_format(&format)
163    }
164}