/// Given a first byte, determines how many bytes are in this UTF-8 character. #[inline] pubfn utf8_char_width(b: u8) -> usize {
UTF8_CHAR_WIDTH[b as usize] as usize
}
letmut i = 0; while i < self.source.len() { let i_ = i;
// SAFETY: `i` starts at `0`, is less than `self.source.len()`, and // only increases, so `0 <= i < self.source.len()`. let byte = unsafe { *self.source.get_unchecked(i) };
i += 1;
if byte < 128 {
} else { let w = utf8_char_width(byte);
macro_rules! error {
() => {{ // SAFETY: We have checked up to `i` that source is valid UTF-8. unsafe { let r = Utf8LossyChunk {
valid: core_str::from_utf8_unchecked(&self.source[0..i_]),
broken: &self.source[i_..i],
}; self.source = &self.source[i..]; return Some(r);
}
}};
}
match w { 2 => { if safe_get(self.source, i) & 192 != TAG_CONT_U8 {
error!();
}
i += 1;
} 3 => { match (byte, safe_get(self.source, i)) {
(0xE0, 0xA0..=0xBF) => (),
(0xE1..=0xEC, 0x80..=0xBF) => (),
(0xED, 0x80..=0x9F) => (),
(0xEE..=0xEF, 0x80..=0xBF) => (),
_ => {
error!();
}
}
i += 1; if safe_get(self.source, i) & 192 != TAG_CONT_U8 {
error!();
}
i += 1;
} 4 => { match (byte, safe_get(self.source, i)) {
(0xF0, 0x90..=0xBF) => (),
(0xF1..=0xF3, 0x80..=0xBF) => (),
(0xF4, 0x80..=0x8F) => (),
_ => {
error!();
}
}
i += 1; if safe_get(self.source, i) & 192 != TAG_CONT_U8 {
error!();
}
i += 1; if safe_get(self.source, i) & 192 != TAG_CONT_U8 {
error!();
}
i += 1;
}
_ => {
error!();
}
}
}
}
let r = Utf8LossyChunk { // SAFETY: We have checked that the entire source is valid UTF-8.
valid: unsafe { core_str::from_utf8_unchecked(self.source) },
broken: &[],
}; self.source = &[];
Some(r)
}
}
impl fmt::Display for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // If we're the empty string then our iterator won't actually yield // anything, so perform the formatting manually ifself.bytes.is_empty() { return"".fmt(f);
}
for Utf8LossyChunk { valid, broken } inself.chunks() { // If we successfully decoded the whole chunk as a valid string then // we can return a direct formatting of the string which will also // respect various formatting flags if possible. if valid.len() == self.bytes.len() {
assert!(broken.is_empty()); return valid.fmt(f);
}
f.write_str(valid)?; if !broken.is_empty() {
f.write_char(char::REPLACEMENT_CHARACTER)?;
}
}
Ok(())
}
}
for Utf8LossyChunk { valid, broken } inself.chunks() { // Valid part. // Here we partially parse UTF-8 again which is suboptimal.
{ letmut from = 0; for (i, c) in valid.char_indices() { let esc = c.escape_debug(); // If char needs escaping, flush backlog so far and write, else skip if esc.len() != 1 {
f.write_str(&valid[from..i])?; for c in esc {
f.write_char(c)?;
}
from = i + c.len_utf8();
}
}
f.write_str(&valid[from..])?;
}
// Broken parts of string as hex escape. for &b in broken {
write!(f, "\\x{:02x}", b)?;
}
}
f.write_char('"')
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.