1use std::path::Path;
7
8const UTF8_BOM_CHAR: char = '\u{FEFF}';
9
10pub fn remove_verbatim_escape_sequences(s: &str) -> String {
11 s.replace("\\r", " ")
12 .replace("\\n", " ")
13 .replace("\\t", " ")
14}
15
16pub fn strip_utf8_bom_str(s: &str) -> &str {
17 s.strip_prefix(UTF8_BOM_CHAR).unwrap_or(s)
18}
19
20pub fn should_remove_verbatim_escape_sequences(path: &Path, is_source: bool) -> bool {
21 if is_source {
22 return true;
23 }
24
25 path.extension()
26 .and_then(|ext| ext.to_str())
27 .is_some_and(|ext| matches!(ext.to_ascii_lowercase().as_str(), "po" | "pot"))
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 #[test]
34 fn test_strip_utf8_bom_str_with_bom() {
35 let s = "\u{FEFF}Hello World";
36 assert_eq!(strip_utf8_bom_str(s), "Hello World");
37 }
38
39 #[test]
40 fn test_strip_utf8_bom_str_without_bom() {
41 let s = "Hello World";
42 assert_eq!(strip_utf8_bom_str(s), "Hello World");
43 }
44
45 #[test]
46 fn test_strip_utf8_bom_str_empty() {
47 let s = "";
48 assert_eq!(strip_utf8_bom_str(s), "");
49 }
50
51 #[test]
52 fn test_strip_utf8_bom_str_only_bom() {
53 let s = "\u{FEFF}";
54 assert_eq!(strip_utf8_bom_str(s), "");
55 }
56
57 #[test]
58 fn test_bom_character_is_not_whitespace() {
59 let s = "\u{FEFF}Hello";
60 assert_ne!(s.trim(), "Hello");
61 assert_eq!(strip_utf8_bom_str(s), "Hello");
62 }
63
64 #[test]
65 fn test_remove_verbatim_escape_sequences_basic() {
66 let input = "line1\\nline2\\rline3\\tline4";
67 let output = remove_verbatim_escape_sequences(input);
68 assert_eq!(output, "line1 line2 line3 line4");
69 }
70
71 #[test]
72 fn test_remove_verbatim_escape_sequences_only_backslash_n() {
73 let input = "hello\\nworld";
74 let output = remove_verbatim_escape_sequences(input);
75 assert_eq!(output, "hello world");
76 }
77
78 #[test]
79 fn test_remove_verbatim_escape_sequences_no_escapes() {
80 let input = "normal text without escapes";
81 let output = remove_verbatim_escape_sequences(input);
82 assert_eq!(output, input);
83 }
84
85 #[test]
86 fn test_remove_verbatim_escape_sequences_actual_newline() {
87 let input = "line1\nline2";
88 let output = remove_verbatim_escape_sequences(input);
89 assert_eq!(output, "line1\nline2");
90 }
91
92 #[test]
93 fn test_remove_verbatim_escape_sequences_multiple() {
94 let input = "a\\nb\\nc\\n";
95 let output = remove_verbatim_escape_sequences(input);
96 assert_eq!(output, "a b c ");
97 }
98
99 #[test]
100 fn test_remove_verbatim_escape_sequences_options_c_sample() {
101 let input = "Try `progname --help' for more information.\\n";
102 let output = remove_verbatim_escape_sequences(input);
103 assert_eq!(output, "Try `progname --help' for more information. ");
104 }
105
106 #[test]
107 fn test_should_remove_verbatim_escape_sequences_for_source_files() {
108 assert!(should_remove_verbatim_escape_sequences(
109 Path::new("main.rs"),
110 true
111 ));
112 }
113
114 #[test]
115 fn test_should_remove_verbatim_escape_sequences_for_po_files() {
116 assert!(should_remove_verbatim_escape_sequences(
117 Path::new("locale.po"),
118 false
119 ));
120 assert!(should_remove_verbatim_escape_sequences(
121 Path::new("template.pot"),
122 false
123 ));
124 }
125
126 #[test]
127 fn test_should_not_remove_verbatim_escape_sequences_for_plain_text() {
128 assert!(!should_remove_verbatim_escape_sequences(
129 Path::new("README.txt"),
130 false
131 ));
132 }
133}