subtitle_translator_cli/
subtitle_file.rs1use std::error::Error;
2
3pub trait SubtitleFile {
4 fn split_contents(&self, contents: &String) -> Result<Vec<String>, Box<dyn Error>>;
5 fn merge_contents(
6 &self,
7 contents: &String,
8 translated_contents: Vec<String>,
9 ) -> Result<String, Box<dyn Error>>;
10}
11
12pub struct SrtFile {}
13
14impl SubtitleFile for SrtFile {
15 fn split_contents(&self, contents: &String) -> Result<Vec<String>, Box<dyn Error>> {
16 let segments = contents.split("\r\n").collect::<Vec<&str>>();
17 let extracted_contents = extract_contents(&segments);
18
19 let extracted_strings: Vec<String> = extracted_contents
20 .into_iter()
21 .map(|s| s.to_string())
22 .collect();
23 Ok(extracted_strings)
24 }
25
26 fn merge_contents(
27 &self,
28 contents: &String,
29 translated_contents: Vec<String>,
30 ) -> Result<String, Box<dyn Error>> {
31 let mut merged_contents = String::new();
32 let mut translated_contents = translated_contents.into_iter();
33 for line in contents.lines() {
34 if is_number(line) || is_timeline(line) || is_empty_line(line) {
35 merged_contents.push_str(format!("{}\n", line).as_str());
36 continue;
37 }
38 merged_contents.push_str(format!("{}\n", line).as_str());
40 match translated_contents.next() {
42 Some(translated_line) => {
43 merged_contents.push_str(format!("{}\n", translated_line).as_str());
44 }
45 None => {
46 merged_contents.push_str(format!("{}\n", line).as_str());
47 }
48 }
49 }
50 Ok(merged_contents)
51 }
52}
53
54fn extract_contents(segments: &[&str]) -> Vec<String> {
55 let mut extracted_contents = Vec::new();
56 for &segment in segments {
57 if is_number(segment) || is_timeline(segment) || is_empty_line(segment) {
58 continue;
59 }
60 extracted_contents.push(segment.to_string());
61 }
62 extracted_contents
63}
64
65fn is_number(s: &str) -> bool {
66 s.chars().all(char::is_numeric)
67}
68
69fn is_timeline(s: &str) -> bool {
70 s.contains("-->")
71}
72
73fn is_empty_line(s: &str) -> bool {
74 s.is_empty()
75}