Skip to main content

dm_database_driver_log/
encoding.rs

1//! 日志文件编码配置与解码。
2
3use encoding::all::GB18030;
4use encoding::{DecoderTrap, Encoding};
5
6/// 文件编码提示,用于指示日志文件的字符编码。
7#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
8pub enum FileEncodingHint {
9    /// 自动探测:每行优先按 UTF-8,失败后按 GB18030 解码。
10    #[default]
11    Auto,
12    /// 文件使用 UTF-8 编码。
13    Utf8,
14    /// 文件使用 GB18030 编码。
15    Gb18030,
16}
17
18/// 将一行日志字节解码成可供解析器借用的 UTF-8 字符串。
19///
20/// 驱动日志通常是 UTF-8,但 DM 部署中也可能出现 GB18030 文件。严格解码
21/// 失败时退回 lossy UTF-8,确保一行坏字符不会让整个流式迭代器失去同步。
22pub(crate) fn decode(bytes: &[u8], hint: FileEncodingHint) -> String {
23    match hint {
24        FileEncodingHint::Utf8 => String::from_utf8_lossy(bytes).into_owned(),
25        FileEncodingHint::Gb18030 => decode_gb18030(bytes),
26        FileEncodingHint::Auto => match std::str::from_utf8(bytes) {
27            Ok(text) => text.to_owned(),
28            Err(_) => decode_gb18030(bytes),
29        },
30    }
31}
32
33fn decode_gb18030(bytes: &[u8]) -> String {
34    GB18030
35        .decode(bytes, DecoderTrap::Strict)
36        .unwrap_or_else(|_| String::from_utf8_lossy(bytes).into_owned())
37}