Estou tentando converter um vetor de bytes ASCII em uma string rust. Encontrei a std::str::from_utf8()
função, que deve ser capaz de manipular todas as strings ASCII. Por algum motivo, ela não consegue ler o símbolo de copyright, como mostrado neste exemplo de código:
let buf = vec![0xA9, 0x41, 0x52, 0x54]; //©ART
println!(
"{}",
match std::str::from_utf8(&buf) {
Ok(x) => x,
Err(x) => {
println!("ERROR: {}", x);
"failed"
}
}
);
// > ERROR: invalid utf-8 sequence of 1 bytes from index 0
De acordo com https://www.ascii-code.com/CP1252/169 0xA9
é um caractere ASCII válido e, de acordo com https://www.compart.com/en/unicode/U+00A9, também é um caractere UTF-8 válido.
Eu também tentei String::from_utf8_lossy()
, mas o resultado que obtive �ART
foi o que a string não deveria ser.
Estou esquecendo de alguma coisa aqui ou é um bug na maneira como o Rust manipula o ASCII?
0xA9
não é ASCII; ASCII é apenas uma codificação de 7 bits e este valor tem o 8º bit definido.Ele pode ser interpretado como ASCII estendido , o que significa que requer pré-conhecimento de um conjunto de caracteres para interpretá-lo como "©". Você pode ver no seu link que é "©" no conjunto de caracteres Windows-1252, mas outro link mostra que
0xA9
é "⌐" no conjunto de caracteres Code page 437. E há muitos outros conjuntos de caracteres.Como
0xA9
não é ASCII, não é UTF8 - pelo menos não sozinho. O 8º bit definido indica que é parte de uma sequência multibyte e, mais importante, a representação de bits de0xA9
começa com10xxxxxx
o que significa que é o meio de uma sequência multibyte (veja UTF8 na wikipedia ). Então, qualquer decodificador UTF8 que encontrar isso (sem um caractere de início multibyte precedente) irá rejeitá-lo.Se você quiser usar um conjunto de caracteres ASCII estendido e decodificá-lo para uma string Rust, você precisaria decodificá-lo de forma diferente. Um crate como encoding-rs provavelmente poderia fazer isso.