(
source: &Wtf8,
preferred_quote: Quote,
length_add: impl Fn(usize, usize) -> Option<usize>,
)
| 148 | } |
| 149 | |
| 150 | fn output_layout_with_checker( |
| 151 | source: &Wtf8, |
| 152 | preferred_quote: Quote, |
| 153 | length_add: impl Fn(usize, usize) -> Option<usize>, |
| 154 | ) -> EscapeLayout { |
| 155 | let mut out_len = Self::REPR_RESERVED_LEN; |
| 156 | let mut single_count = 0; |
| 157 | let mut double_count = 0; |
| 158 | |
| 159 | for ch in source.code_points() { |
| 160 | let incr = match ch.to_char() { |
| 161 | Some('\'') => { |
| 162 | single_count += 1; |
| 163 | 1 |
| 164 | } |
| 165 | Some('"') => { |
| 166 | double_count += 1; |
| 167 | 1 |
| 168 | } |
| 169 | _ => Self::escaped_char_len(ch), |
| 170 | }; |
| 171 | let Some(new_len) = length_add(out_len, incr) else { |
| 172 | #[cold] |
| 173 | const fn stop( |
| 174 | single_count: usize, |
| 175 | double_count: usize, |
| 176 | preferred_quote: Quote, |
| 177 | ) -> EscapeLayout { |
| 178 | EscapeLayout { |
| 179 | quote: choose_quote(single_count, double_count, preferred_quote).0, |
| 180 | len: None, |
| 181 | } |
| 182 | } |
| 183 | return stop(single_count, double_count, preferred_quote); |
| 184 | }; |
| 185 | out_len = new_len; |
| 186 | } |
| 187 | |
| 188 | let (quote, num_escaped_quotes) = choose_quote(single_count, double_count, preferred_quote); |
| 189 | // we'll be adding backslashes in front of the existing inner quotes |
| 190 | let Some(out_len) = length_add(out_len, num_escaped_quotes) else { |
| 191 | return EscapeLayout { quote, len: None }; |
| 192 | }; |
| 193 | |
| 194 | EscapeLayout { |
| 195 | quote, |
| 196 | len: Some(out_len - Self::REPR_RESERVED_LEN), |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | fn escaped_char_len(ch: CodePoint) -> usize { |
| 201 | // surrogates are \uHHHH |
nothing calls this directly
no test coverage detected