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 {
50 s.replace('\\', "\\\\")
51 .replace('"', "\\\"")
52 .replace('\n', "\\n")
53 .replace('\r', "\\r")
54 .replace('\t', "\\t")
55 .replace('`', "\\`")
56 .replace('$', "\\$")
57}
58
59pub fn go_string_literal(s: &str) -> String {
61 if !s.contains('`') {
62 format!("`{s}`")
63 } else {
64 format!("\"{}\"", escape_go(s))
65 }
66}
67
68pub fn escape_go(s: &str) -> String {
70 s.replace('\\', "\\\\")
71 .replace('"', "\\\"")
72 .replace('\n', "\\n")
73 .replace('\r', "\\r")
74 .replace('\t', "\\t")
75}
76
77pub fn escape_java(s: &str) -> String {
79 s.replace('\\', "\\\\")
80 .replace('"', "\\\"")
81 .replace('\n', "\\n")
82 .replace('\r', "\\r")
83 .replace('\t', "\\t")
84}
85
86pub fn escape_csharp(s: &str) -> String {
88 s.replace('\\', "\\\\")
89 .replace('"', "\\\"")
90 .replace('\n', "\\n")
91 .replace('\r', "\\r")
92 .replace('\t', "\\t")
93}
94
95pub fn escape_php(s: &str) -> String {
97 s.replace('\\', "\\\\")
98 .replace('"', "\\\"")
99 .replace('$', "\\$")
100 .replace('\n', "\\n")
101 .replace('\r', "\\r")
102 .replace('\t', "\\t")
103}
104
105pub fn escape_ruby(s: &str) -> String {
107 s.replace('\\', "\\\\")
108 .replace('"', "\\\"")
109 .replace('#', "\\#")
110 .replace('\n', "\\n")
111 .replace('\r', "\\r")
112 .replace('\t', "\\t")
113}
114
115pub fn escape_elixir(s: &str) -> String {
117 s.replace('\\', "\\\\")
118 .replace('"', "\\\"")
119 .replace('#', "\\#")
120 .replace('\n', "\\n")
121 .replace('\r', "\\r")
122 .replace('\t', "\\t")
123}
124
125pub fn escape_r(s: &str) -> String {
127 s.replace('\\', "\\\\")
128 .replace('"', "\\\"")
129 .replace('\n', "\\n")
130 .replace('\r', "\\r")
131 .replace('\t', "\\t")
132}
133
134pub fn escape_c(s: &str) -> String {
136 s.replace('\\', "\\\\")
137 .replace('"', "\\\"")
138 .replace('\n', "\\n")
139 .replace('\r', "\\r")
140 .replace('\t', "\\t")
141}
142
143pub fn sanitize_ident(s: &str) -> String {
146 let mut result = String::with_capacity(s.len());
147 for ch in s.chars() {
148 if ch.is_ascii_alphanumeric() || ch == '_' {
149 result.push(ch);
150 } else {
151 result.push('_');
152 }
153 }
154 let trimmed = result.trim_start_matches(|c: char| c.is_ascii_digit());
156 if trimmed.is_empty() {
157 "_".to_string()
158 } else {
159 trimmed.to_string()
160 }
161}
162
163pub fn sanitize_filename(s: &str) -> String {
165 s.chars()
166 .map(|c| if c.is_ascii_alphanumeric() || c == '_' { c } else { '_' })
167 .collect::<String>()
168 .to_lowercase()
169}