feat: ddddocr-rs 完成 core/ort/tract2 规范整改与发布

准备

  - core:内置官方字符集(OLD/BETA)与 ModelMetadata::from_builtin_*
  构造器
  - ort:导出 Session、实现 Info、修正 cuda feature 接线、共享推理工具
  - tract2:包名更名(原 ddddocr-tract 已被占用)并完成规范整改
  - 集成测试按领域拆分(ocr / det / slide / common / api_surface)
  - 发布准备:Cargo.toml 元数据、workspace 版本 0.2.4、LICENSE/
  NOTICE、README 模型下载说明
This commit is contained in:
2026-08-10 19:56:29 +08:00
parent fe61895926
commit 00e8ab5308
58 changed files with 2542 additions and 2237 deletions

View File

@@ -1,7 +1,10 @@
use ort::Error as OrtError;
/// 模型加载与解析的通用结果类型。
pub type Result<T> = std::result::Result<T, Error>;
#[derive(thiserror::Error, Debug)]
/// 模型加载、解析与 Session 构建阶段的错误。
pub enum Error {
/// 底层构建器配置失败。
#[error("builder构建失败")]
Build(#[from] BuildError),
/// 解析 ONNX 模型/路径失败(如文件损坏、算子不支持、路径非法)
@@ -9,11 +12,11 @@ pub enum Error {
ModelParse(#[from] ParseError),
/// 模型计算图优化失败(如常量折叠、形状推导失败)
#[error("优化 Tract 模型图失败: {0}")]
#[error("优化 ORT 模型图失败: {0}")]
OptimizationFailed(#[source] OrtError),
/// 构建可执行 Session 失败(如输入输出 Tensor 类型/形状未确定)
#[error("构建可运行 Tract 实例失败: {0}")]
#[error("构建可运行的 ORT Session 失败: {0}")]
RunnableBuildFailed(#[source] OrtError),
/// JSON 反序列化失败(自动透传 serde_json 报错)
@@ -24,6 +27,7 @@ pub enum Error {
#[error("Metadata 字节流不是合法的 UTF-8 编码: {0}")]
InvalidUtf8(#[from] std::str::Utf8Error),
/// 模型元数据内容解析失败。
#[error("模型元数据解析失败: {0}")]
MetadataParse(String),
@@ -32,8 +36,6 @@ pub enum Error {
Other(String, #[source] Box<dyn std::error::Error + Send + Sync>),
}
impl Error {
/// 方便将任何第三方 Error 包装为 Error::Other
pub fn new<E>(msg: impl Into<String>, err: E) -> Self
@@ -44,6 +46,7 @@ impl Error {
}
}
#[derive(thiserror::Error, Debug)]
/// 从路径或字节流解析 ONNX 模型失败的错误。
pub enum ParseError {
/// 策略 A从文件路径加载失败附带路径上下文信息方便排查是找不到文件还是格式不对
#[error("从路径 '{0}' 加载 ONNX 模型失败: {1}")]
@@ -54,13 +57,45 @@ pub enum ParseError {
Bytes(#[source] OrtError),
}
#[derive(thiserror::Error, Debug)]
pub enum BuildError{
#[error("builder构建失败")]
pub enum BuildError {
/// 底层 SessionBuilder 构建失败
#[error("构建 ORT SessionBuilder 失败: {0}")]
BuildFailed(#[from] OrtError),
#[error("builder构建失败")]
/// 线程数配置失败。
#[error("{0}")]
Threads(String),
#[error("builder构建失败")]
/// 启用 CUDA 执行提供者失败。
#[error("{0}")]
EnabledCudaFailed(String),
#[error("builder构建失败")]
NotEnabledCuda(String)
}
/// 未编译 CUDA 支持时尝试启用 GPU。
#[error("{0}")]
NotEnabledCuda(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wraps_external_error_via_new() {
let io_err = std::io::Error::other("boom");
let err = Error::new("自定义错误", io_err);
assert!(matches!(err, Error::Other(_, _)));
assert!(err.to_string().contains("自定义错误"));
}
#[test]
fn serde_json_error_converts_to_error() {
let json_err = serde_json::from_str::<serde_json::Value>("{").unwrap_err();
let err: Error = json_err.into();
assert!(matches!(err, Error::JsonParse(_)));
}
#[test]
fn ut8_error_converts_to_error() {
let bytes = vec![0xffu8];
let utf8_err = std::str::from_utf8(&bytes).unwrap_err();
let err: Error = utf8_err.into();
assert!(matches!(err, Error::InvalidUtf8(_)));
}
}