Skip to main content

a3s_use_ocr/
models.rs

1use std::path::PathBuf;
2
3use a3s_use_core::{Artifact, Readiness};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
7#[serde(rename_all = "camelCase")]
8pub struct OcrRequest {
9    #[schemars(description = "Local PNG, JPEG, WebP, GIF, BMP, or TIFF image path")]
10    pub path: PathBuf,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
14#[serde(rename_all = "camelCase")]
15pub struct OcrPoint {
16    pub x: u32,
17    pub y: u32,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
21#[serde(rename_all = "camelCase")]
22pub struct OcrBoundingBox {
23    pub x: u32,
24    pub y: u32,
25    pub width: u32,
26    pub height: u32,
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, schemars::JsonSchema)]
30#[serde(rename_all = "camelCase")]
31pub struct OcrBlock {
32    pub page: u32,
33    pub text: String,
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    #[schemars(description = "Provider recognition confidence from 0 through 1, when available")]
36    pub confidence: Option<f32>,
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    #[schemars(
39        description = "Provider text-detection confidence from 0 through 1, when available"
40    )]
41    pub detection_confidence: Option<f32>,
42    #[serde(default, skip_serializing_if = "Option::is_none")]
43    #[schemars(description = "Four polygon vertices in source-image coordinates, when available")]
44    pub polygon: Option<[OcrPoint; 4]>,
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub bounding_box: Option<OcrBoundingBox>,
47}
48
49#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, schemars::JsonSchema)]
50#[serde(rename_all = "camelCase")]
51pub struct OcrResult {
52    pub provider: String,
53    pub engine: String,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub model: Option<String>,
56    #[schemars(with = "OcrArtifactSchema")]
57    pub source: Artifact,
58    pub text: String,
59    #[serde(default, skip_serializing_if = "Vec::is_empty")]
60    pub blocks: Vec<OcrBlock>,
61    #[serde(default, skip_serializing_if = "Vec::is_empty")]
62    pub warnings: Vec<String>,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
66#[serde(rename_all = "camelCase")]
67pub struct OcrDiagnostic {
68    #[schemars(with = "OcrReadinessSchema")]
69    pub readiness: Readiness,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub provider: Option<String>,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub engine: Option<String>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub model: Option<String>,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub model_dir: Option<PathBuf>,
78    pub sends_source_off_device: bool,
79    pub message: String,
80    #[serde(default, skip_serializing_if = "Vec::is_empty")]
81    pub suggestions: Vec<String>,
82}
83
84#[derive(schemars::JsonSchema)]
85#[allow(dead_code)]
86struct OcrArtifactSchema {
87    path: PathBuf,
88    media_type: String,
89    size: u64,
90    sha256: String,
91}
92
93#[derive(schemars::JsonSchema)]
94#[serde(rename_all = "kebab-case")]
95#[allow(dead_code)]
96enum OcrReadinessSchema {
97    Ready,
98    Missing,
99    Broken,
100    Unknown,
101}