1pub fn escape_python(s: &str) -> String {
5 s.replace('\\', "\\\\")
6 .replace('"', "\\\"")
7 .replace('\n', "\\n")
8 .replace('\r', "\\r")
9 .replace('\t', "\\t")
10}
11
12pub fn escape_rust(s: &str) -> String {
14 s.replace('\\', "\\\\")
15 .replace('"', "\\\"")
16 .replace('\n', "\\n")
17 .replace('\r', "\\r")
18 .replace('\t', "\\t")
19}
20
21pub fn raw_string_hashes(s: &str) -> usize {
23 let mut max_hashes = 0;
24 let mut current = 0;
25 let mut after_quote = false;
26 for ch in s.chars() {
27 if ch == '"' {
28 after_quote = true;
29 current = 0;
30 } else if ch == '#' && after_quote {
31 current += 1;
32 max_hashes = max_hashes.max(current);
33 } else {
34 after_quote = false;
35 current = 0;
36 }
37 }
38 max_hashes + 1
39}
40
41pub fn rust_raw_string(s: &str) -> String {
43 let hashes = raw_string_hashes(s);
44 let h: String = "#".repeat(hashes);
45 format!("r{h}\"{s}\"{h}")
46}
47
48pub fn escape_js(s: &str) -> String {
53 s.replace('\\', "\\\\")
54 .replace('"', "\\\"")
55 .replace('\n', "\\n")
56 .replace('\r', "\\r")
57 .replace('\t', "\\t")
58}
59
60pub fn escape_js_template(s: &str) -> String {
65 s.replace('\\', "\\\\")
66 .replace('`', "\\`")
67 .replace('$', "\\$")
68}
69
70pub fn go_string_literal(s: &str) -> String {
72 if !s.contains('`') {
73 format!("`{s}`")
74 } else {
75 format!("\"{}\"", escape_go(s))
76 }
77}
78
79pub fn escape_go(s: &str) -> String {
81 s.replace('\\', "\\\\")
82 .replace('"', "\\\"")
83 .replace('\n', "\\n")
84 .replace('\r', "\\r")
85 .replace('\t', "\\t")
86}
87
88pub fn escape_java(s: &str) -> String {
90 s.replace('\\', "\\\\")
91 .replace('"', "\\\"")
92 .replace('\n', "\\n")
93 .replace('\r', "\\r")
94 .replace('\t', "\\t")
95}
96
97pub fn escape_csharp(s: &str) -> String {
99 s.replace('\\', "\\\\")
100 .replace('"', "\\\"")
101 .replace('\n', "\\n")
102 .replace('\r', "\\r")
103 .replace('\t', "\\t")
104}
105
106pub fn escape_php(s: &str) -> String {
108 s.replace('\\', "\\\\")
109 .replace('"', "\\\"")
110 .replace('$', "\\$")
111 .replace('\n', "\\n")
112 .replace('\r', "\\r")
113 .replace('\t', "\\t")
114}
115
116pub fn escape_ruby(s: &str) -> String {
118 s.replace('\\', "\\\\")
119 .replace('"', "\\\"")
120 .replace('#', "\\#")
121 .replace('\n', "\\n")
122 .replace('\r', "\\r")
123 .replace('\t', "\\t")
124}
125
126pub fn escape_ruby_single(s: &str) -> String {
129 s.replace('\\', "\\\\").replace('\'', "\\'")
130}
131
132pub fn ruby_needs_double_quotes(s: &str) -> bool {
135 s.contains('\n') || s.contains('\r') || s.contains('\t') || s.contains('\0')
136}
137
138pub fn ruby_string_literal(s: &str) -> String {
140 if ruby_needs_double_quotes(s) {
141 format!("\"{}\"", escape_ruby(s))
142 } else {
143 format!("'{}'", escape_ruby_single(s))
144 }
145}
146
147pub fn escape_elixir(s: &str) -> String {
149 s.replace('\\', "\\\\")
150 .replace('"', "\\\"")
151 .replace('#', "\\#")
152 .replace('\n', "\\n")
153 .replace('\r', "\\r")
154 .replace('\t', "\\t")
155}
156
157pub fn escape_r(s: &str) -> String {
159 s.replace('\\', "\\\\")
160 .replace('"', "\\\"")
161 .replace('\n', "\\n")
162 .replace('\r', "\\r")
163 .replace('\t', "\\t")
164}
165
166pub fn escape_c(s: &str) -> String {
168 s.replace('\\', "\\\\")
169 .replace('"', "\\\"")
170 .replace('\n', "\\n")
171 .replace('\r', "\\r")
172 .replace('\t', "\\t")
173}
174
175pub fn sanitize_ident(s: &str) -> String {
178 let mut result = String::with_capacity(s.len());
179 for ch in s.chars() {
180 if ch.is_ascii_alphanumeric() || ch == '_' {
181 result.push(ch);
182 } else {
183 result.push('_');
184 }
185 }
186 let trimmed = result.trim_start_matches(|c: char| c.is_ascii_digit());
188 if trimmed.is_empty() {
189 "_".to_string()
190 } else {
191 trimmed.to_string()
192 }
193}
194
195pub fn sanitize_filename(s: &str) -> String {
197 s.chars()
198 .map(|c| if c.is_ascii_alphanumeric() || c == '_' { c } else { '_' })
199 .collect::<String>()
200 .to_lowercase()
201}
202
203pub fn escape_shell(s: &str) -> String {
209 s.replace('\'', r"'\''")
210}