///|
/// 二进制整数的字节序。
pub(all) enum Endian {
Big
Little
} derive(Eq, Debug, ToJson)
///|
pub extend Endian with Eq::{not_equal, equal}
///|
pub extend Endian with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend Endian with ToJson::{to_json}
///|
/// 统一的编解码错误分类。
pub(all) enum ErrorKind {
UnexpectedEof
Misaligned
InvalidValue
LimitExceeded
ChecksumMismatch
TrailingBytes
Unsupported
} derive(Eq, Debug, ToJson)
///|
pub extend ErrorKind with Eq::{not_equal, equal}
///|
pub extend ErrorKind with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend ErrorKind with ToJson::{to_json}
///|
/// 带绝对偏移和字段路径的错误。
pub struct BinError {
kind : ErrorKind
offset : Int
path : String
message : String
} derive(Eq, Debug, ToJson)
///|
pub extend BinError with Eq::{not_equal, equal}
///|
pub extend BinError with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend BinError with ToJson::{to_json}
///|
pub fn BinError::new(
kind : ErrorKind,
offset : Int,
path : String,
message : String,
) -> BinError {
{ kind, offset, path, message, }
}
///|
/// 生成适合 CLI 和日志输出的稳定错误文本。
pub fn BinError::render(self : BinError) -> String {
let location = if self.path == "" {
"offset \{self.offset}"
} else {
"\{self.path} at offset \{self.offset}"
}
"\{self.kind.name()} (\{location}): \{self.message}"
}
///|
pub fn ErrorKind::name(self : ErrorKind) -> String {
match self {
UnexpectedEof => "UnexpectedEof"
Misaligned => "Misaligned"
InvalidValue => "InvalidValue"
LimitExceeded => "LimitExceeded"
ChecksumMismatch => "ChecksumMismatch"
TrailingBytes => "TrailingBytes"
Unsupported => "Unsupported"
}
}
///|
/// 字段的解析轨迹,可用于 CLI 和浏览器可视化。
pub struct TraceEntry {
path : String
kind : String
start : Int
end : Int
value : String
} derive(Eq, Debug, ToJson)
///|
pub extend TraceEntry with Eq::{not_equal, equal}
///|
pub extend TraceEntry with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend TraceEntry with ToJson::{to_json}
///|
/// 防止恶意长度字段造成过量内存或递归消耗。
pub struct Limits {
max_input_bytes : Int
max_collection_length : Int
max_depth : Int
max_output_bytes : Int
max_trace_entries : Int
} derive(Eq, Debug)
///|
pub extend Limits with Eq::{not_equal, equal}
///|
pub extend Limits with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub fn Limits::new(
max_input_bytes? : Int = 64 * 1024 * 1024,
max_collection_length? : Int = 1_000_000,
max_depth? : Int = 64,
max_output_bytes? : Int = 64 * 1024 * 1024,
max_trace_entries? : Int = 100_000,
) -> Limits {
{
max_input_bytes,
max_collection_length,
max_depth,
max_output_bytes,
max_trace_entries,
}
}
///|
pub fn Limits::default() -> Limits {
Limits::new()
}
///|
pub(all) struct DecodeOptions {
limits : Limits
require_eof : Bool
} derive(Eq, Debug)
///|
pub extend DecodeOptions with Eq::{not_equal, equal}
///|
pub extend DecodeOptions with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub fn DecodeOptions::default() -> DecodeOptions {
{ limits: Limits::default(), require_eof: true, }
}
///|
pub(all) struct EncodeOptions {
limits : Limits
} derive(Eq, Debug)
///|
pub extend EncodeOptions with Eq::{not_equal, equal}
///|
pub extend EncodeOptions with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub fn EncodeOptions::default() -> EncodeOptions {
{ limits: Limits::default(), }
}
///|
/// 解码成功后的值、消费字节数和字段轨迹。
pub struct Decoded[T] {
value : T
consumed : Int
trace : Array[TraceEntry]
} derive(Debug)
///|
pub extend Decoded with @moonbitlang/core/debug.Debug::{to_repr}