(
mut ctx: Ctx,
errors: &E,
err_reason: &str,
target_kind: StrKind,
)
| 209 | |
| 210 | #[inline] |
| 211 | fn encode_utf8_compatible<Ctx, E>( |
| 212 | mut ctx: Ctx, |
| 213 | errors: &E, |
| 214 | err_reason: &str, |
| 215 | target_kind: StrKind, |
| 216 | ) -> Result<Vec<u8>, Ctx::Error> |
| 217 | where |
| 218 | Ctx: EncodeContext, |
| 219 | E: EncodeErrorHandler<Ctx>, |
| 220 | { |
| 221 | // let mut data = s.as_ref(); |
| 222 | // let mut char_data_index = 0; |
| 223 | let mut out = Vec::<u8>::with_capacity(ctx.remaining_data().len()); |
| 224 | loop { |
| 225 | let data = ctx.remaining_data(); |
| 226 | let mut iter = iter_code_points(data); |
| 227 | let Some((i, _)) = iter.find(|(_, c)| !target_kind.can_encode(*c)) else { |
| 228 | break; |
| 229 | }; |
| 230 | |
| 231 | out.extend_from_slice(&ctx.remaining_data().as_bytes()[..i.bytes]); |
| 232 | |
| 233 | let err_start = ctx.position() + i; |
| 234 | // number of non-compatible chars between the first non-compatible char and the next compatible char |
| 235 | let err_end = match { iter }.find(|(_, c)| target_kind.can_encode(*c)) { |
| 236 | Some((i, _)) => ctx.position() + i, |
| 237 | None => ctx.data_len(), |
| 238 | }; |
| 239 | |
| 240 | let range = err_start..err_end; |
| 241 | let replace = ctx.handle_error(errors, range.clone(), Some(err_reason))?; |
| 242 | match replace { |
| 243 | EncodeReplace::Str(s) => { |
| 244 | if s.is_compatible_with(target_kind) { |
| 245 | out.extend_from_slice(s.as_ref().as_bytes()); |
| 246 | } else { |
| 247 | return Err(ctx.error_encoding(range, Some(err_reason))); |
| 248 | } |
| 249 | } |
| 250 | EncodeReplace::Bytes(b) => { |
| 251 | out.extend_from_slice(b.as_ref()); |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | out.extend_from_slice(ctx.remaining_data().as_bytes()); |
| 256 | Ok(out) |
| 257 | } |
| 258 | |
| 259 | pub mod errors { |
| 260 | use crate::str::UnicodeEscapeCodepoint; |
no test coverage detected