1use hex_color::HexColor;
2use serde::{Deserialize, Serialize};
3use serde_repr::{Deserialize_repr, Serialize_repr};
4#[derive(Debug, Serialize, Deserialize)]
5#[serde(rename = "timedtext")]
6pub struct TimedText {
9 #[serde(rename = "format")]
10 pub format: Option<String>,
11 pub head: Option<Head>,
12 pub body: Body,
13}
14impl TimedText {
15 pub fn from_str(s: &str) -> Result<Self, quick_xml::DeError> {
16 quick_xml::de::from_str(s)
17 }
18}
19
20#[derive(Debug, Serialize, Deserialize)]
21pub struct Head {
22 #[serde(rename = "pen")]
23 pub pen: Vec<Pen>,
24 #[serde(rename = "wp")]
25 pub wp: Vec<WindowPosition>,
26 #[serde(rename = "ws")]
27 pub ws: Vec<WindowStyle>,
28}
29
30#[derive(Debug, Serialize, Deserialize)]
31pub struct Pen {
44 #[serde(rename = "@id")]
46 pub id: Option<u32>,
47
48 #[serde(rename = "@b")]
50 pub bold: Option<bool>,
52
53 #[serde(rename = "@i")]
54 pub italic: Option<bool>,
56
57 #[serde(rename = "@u")]
58 pub underline: Option<bool>,
60
61 #[serde(rename = "@fc")]
63 pub foreground_color: Option<HexColor>,
64
65 #[serde(rename = "@fo")]
71 pub foreground_opacity: Option<u32>,
72
73 #[serde(rename = "@bc")]
75 pub background_color: Option<HexColor>,
76
77 #[serde(rename = "@bo")]
83 pub background_opacity: Option<u32>,
84
85 #[serde(rename = "@ec")]
87 pub edge_color: Option<HexColor>,
88
89 #[serde(rename = "@et")]
91 pub edge_type: Option<u32>,
92
93 #[serde(rename = "@sz")]
95 pub font_size: Option<u32>,
96
97 #[serde(rename = "@fs")]
98 pub font_style: Option<FontStyle>,
100
101 #[serde(rename = "@rb")]
102 pub ruby: Option<RubyPart>,
124
125 #[serde(rename = "@hg")]
126 pub packing: Option<u32>,
128}
129
130#[derive(Debug, Serialize_repr, Deserialize_repr)]
131#[repr(u32)]
132pub enum RubyPart {
133 None = 0,
134 Base = 1,
135 Parenthesis = 2,
136 BeforeText = 4,
137 AfterText = 5,
138}
139
140#[derive(Debug, Serialize_repr, Deserialize_repr)]
141#[repr(u32)]
142pub enum FontStyle {
143 CourierNew = 1,
144 TimesNewRoman = 2,
145 LucidaConsole = 3,
146 ComicSans = 5,
147 MonotypeCorsiva = 6,
148 CarriosGothic = 7,
149 #[serde(other)]
150 Roboto = 0,
151}
152
153impl Default for FontStyle {
154 fn default() -> Self {
155 FontStyle::Roboto
156 }
157}
158
159#[derive(Debug, Serialize_repr, Deserialize_repr)]
160#[repr(u32)]
161pub enum AnchorPoint {
162 TopLeft = 0,
163 TopCenter = 1,
164 TopRight = 2,
165 MiddleLeft = 3,
166 Center = 4,
167 MiddleRight = 5,
168 BottomLeft = 6,
169 BottomCenter = 7,
170 BottomRight = 8,
171}
172
173#[derive(Debug, Serialize, Deserialize)]
174#[serde(rename = "wp")]
176pub struct WindowPosition {
177 #[serde(rename = "@id")]
179 pub id: u32,
180 #[serde(rename = "@ap")]
181 pub anchor_point: Option<AnchorPoint>,
184
185 #[serde(rename = "@ah")]
187 pub anchor_horizontal: Option<i32>,
188
189 #[serde(rename = "@av")]
191 pub anchor_vertical: Option<i32>,
192}
193
194#[derive(Debug, Serialize, Deserialize)]
195#[serde(rename = "ws")]
196pub struct WindowStyle {
197 #[serde(rename = "@id")]
198 pub id: u32,
199 #[serde(rename = "@ju")]
200 pub justify: Option<u32>,
202
203 #[serde(rename = "@pd")]
206 pub pitch_direction: Option<Rotation>,
207
208 #[serde(rename = "@sd")]
210 pub skew_direction: Option<Rotation>,
211}
212
213#[derive(Debug, Serialize_repr, Deserialize_repr)]
214#[repr(u32)]
215pub enum Rotation {
216 Zero = 0,
217 Ninety = 1,
218 OneEighty = 2,
219 TwoSeventy = 3,
220}
221
222#[derive(Debug, Serialize, Deserialize)]
223pub struct Body {
224 #[serde(rename = "$value")]
226 pub elements: Vec<BodyElement>,
227}
228
229#[derive(Debug, Serialize, Deserialize)]
235pub struct Paragraph {
236 #[serde(rename = "$value")]
239 pub inner: Vec<BodyElement>,
241 #[serde(rename = "@t")]
243 pub timestamp: u64,
244 #[serde(rename = "@d")]
246 pub duration: u64,
247
248 #[serde(rename = "@wp")]
250 pub window_position: Option<u32>,
251
252 #[serde(rename = "@ws")]
254 pub window_style: Option<u32>,
255}
256
257#[derive(Debug, Serialize, Deserialize)]
260pub struct Span {
261 #[serde(rename = "$value")]
262 pub inner: Option<Vec<BodyElement>>,
263 #[serde(rename = "p")]
265 pub pen: Option<u32>,
266 }
269#[derive(Debug, Serialize, Deserialize)]
270pub struct Br;
271#[derive(Debug, Serialize, Deserialize)]
272pub struct Div {
273 #[serde(rename = "$value")]
274 pub elements: Vec<BodyElement>,
275}
276
277#[derive(Debug, Serialize, Deserialize)]
278pub enum BodyElement {
279 #[serde(rename = "$text")]
280 Text(String),
281 #[serde(rename = "p")]
282 Paragraph(Paragraph),
283 #[serde(rename = "s")]
284 Span(Span),
285 #[serde(rename = "br")]
286 Br(Br),
287 #[serde(rename = "div")]
288 Div(Vec<Self>),
289}
290
291#[cfg(test)]
292mod tests {
293 use super::*;
294
295 #[test]
298 fn test_parse_file() {
299 let file = include_str!("../test/aishite.srv3");
300 let parse = TimedText::from_str(file).unwrap();
301
302 println!("{:#?}", parse);
303 }
304
305 #[test]
306 fn test_parse_file_unformatted() {
307 let file = include_str!("../test/mesmerizer.srv3.xml");
308 let parse = TimedText::from_str(file).unwrap();
309
310 println!("{:#?}", parse);
311 }
312}