subx_cli/core/formats/
transformers.rs1use crate::core::formats::converter::FormatConverter;
2use crate::core::formats::{Subtitle, SubtitleFormatType};
3
4impl FormatConverter {
5 pub(crate) fn transform_subtitle(
7 &self,
8 subtitle: Subtitle,
9 target_format: &str,
10 ) -> crate::Result<Subtitle> {
11 match (subtitle.format.as_str(), target_format) {
12 ("srt", "ass") => self.srt_to_ass(subtitle),
13 ("ass", "srt") => self.ass_to_srt(subtitle),
14 ("srt", "vtt") => self.srt_to_vtt(subtitle),
15 ("vtt", "srt") => self.vtt_to_srt(subtitle),
16 ("ass", "vtt") => self.ass_to_vtt(subtitle),
17 ("vtt", "ass") => self.vtt_to_ass(subtitle),
18 (source, target) if source == target => Ok(subtitle),
19 _ => Err(crate::error::SubXError::subtitle_format(
20 subtitle.format.to_string(),
21 format!("不支援的轉換: {} -> {}", subtitle.format, target_format),
22 )),
23 }
24 }
25
26 pub(crate) fn srt_to_ass(&self, mut subtitle: Subtitle) -> crate::Result<Subtitle> {
28 let _default_style = crate::core::formats::ass::AssStyle {
29 name: "Default".to_string(),
30 font_name: "Arial".to_string(),
31 font_size: 16,
32 primary_color: crate::core::formats::ass::Color::white(),
33 secondary_color: crate::core::formats::ass::Color::red(),
34 outline_color: crate::core::formats::ass::Color::black(),
35 shadow_color: crate::core::formats::ass::Color::black(),
36 bold: false,
37 italic: false,
38 underline: false,
39 alignment: 2,
40 };
41 for entry in &mut subtitle.entries {
42 if self.config.preserve_styling {
43 entry.styling = Some(self.extract_srt_styling(&entry.text)?);
44 }
45 entry.text = self.convert_srt_tags_to_ass(&entry.text);
46 }
47 subtitle.format = SubtitleFormatType::Ass;
48 subtitle.metadata.original_format = SubtitleFormatType::Srt;
49 Ok(subtitle)
50 }
51
52 pub(crate) fn ass_to_srt(&self, mut subtitle: Subtitle) -> crate::Result<Subtitle> {
54 for entry in &mut subtitle.entries {
55 entry.text = self.strip_ass_tags(&entry.text);
56 if self.config.preserve_styling {
57 entry.text = self.convert_ass_tags_to_srt(&entry.text);
58 }
59 entry.styling = None;
60 }
61 subtitle.format = SubtitleFormatType::Srt;
62 Ok(subtitle)
63 }
64
65 pub(crate) fn srt_to_vtt(&self, mut subtitle: Subtitle) -> crate::Result<Subtitle> {
67 subtitle.metadata.title = Some("WEBVTT".to_string());
68 for entry in &mut subtitle.entries {
69 entry.text = self.convert_srt_tags_to_vtt(&entry.text);
70 }
71 subtitle.format = SubtitleFormatType::Vtt;
72 Ok(subtitle)
73 }
74
75 pub(crate) fn ass_to_vtt(&self, subtitle: Subtitle) -> crate::Result<Subtitle> {
77 let subtitle = self.ass_to_srt(subtitle)?;
79 self.srt_to_vtt(subtitle)
80 }
81
82 pub(crate) fn vtt_to_srt(&self, mut subtitle: Subtitle) -> crate::Result<Subtitle> {
84 for entry in &mut subtitle.entries {
86 if self.config.preserve_styling {
87 entry.text = self.convert_vtt_tags_to_srt(&entry.text);
88 } else {
89 entry.text = self.strip_vtt_tags(&entry.text);
90 }
91 entry.styling = None;
92 }
93 subtitle.format = SubtitleFormatType::Srt;
94 Ok(subtitle)
95 }
96
97 pub(crate) fn vtt_to_ass(&self, subtitle: Subtitle) -> crate::Result<Subtitle> {
99 let subtitle = self.vtt_to_srt(subtitle)?;
101 self.srt_to_ass(subtitle)
102 }
103}