// tag_error.mbt
//
// 音频文件是外部不可信输入:截断、非法字段、超界尺寸都必须落到结构化
// 错误上,绝不能 panic。所有解析入口返回 Result 或 raise TagError。
///|
/// 标签解析与写入过程中可能出现的错误。
pub suberror TagError {
/// 数据长度不足(文件被截断)。
Truncated(offset~ : Int32, need~ : Int32, actual~ : Int32)
/// 数据开头不是本格式的魔数。
NotTagged(format~ : String)
/// 标签头字段非法(版本、flags、尺寸等)。
BadHeader(reason~ : String)
/// 帧头字段非法。
BadFrameHeader(reason~ : String)
/// 帧声明尺寸超出标签或文件边界。
FrameOutOfBounds(frame_id~ : String, size~ : Int32, available~ : Int32)
/// 帧载荷内容非法(编码字节、终止符、字段长度等)。
BadFrameData(frame_id~ : String, reason~ : String)
/// 合法但当前版本尚未实现(加密帧、压缩帧等)。
Unsupported(what~ : String)
/// 不支持的版本号(如 ID3v2.5 或更高)。
UnsupportedVersion(version~ : Int32)
}
///|
/// 把错误渲染为一句中文说明(CLI 与日志用;不含隐藏内部量)。
pub fn TagError::message(self : TagError) -> String {
match self {
Truncated(offset~, need~, actual~) =>
"数据被截断:偏移 \{offset} 处需要 \{need} 字节,实际只有 \{actual} 字节"
NotTagged(format~) => "文件不是 \{format} 标签"
BadHeader(reason~) => "标签头非法:\{reason}"
BadFrameHeader(reason~) => "帧头非法:\{reason}"
FrameOutOfBounds(frame_id~, size~, available~) =>
"帧 \{frame_id} 声明 \{size} 字节,但标签内只剩 \{available} 字节"
BadFrameData(frame_id~, reason~) =>
"帧 \{frame_id} 载荷非法:\{reason}"
Unsupported(what~) => "暂不支持:\{what}"
UnsupportedVersion(version~) => "不支持的标签版本:\{version}"
}
}