use serde::{Deserialize, Serialize};
use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct OcrResponse {
pub task_id: String,
pub message: String,
pub status: OcrStatus,
pub words_result_num: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub words_result: Option<Vec<WordsResultItem>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum OcrStatus {
Succeeded,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct WordsResultItem {
pub location: Location,
pub words: String,
pub probability: Probability,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct Location {
pub left: i64,
pub top: i64,
pub width: i64,
pub height: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct Probability {
pub average: f64,
pub variance: f64,
pub min: f64,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn top_level_required_fields_and_status_enum_are_enforced() {
let valid = serde_json::json!({
"task_id": "ocr-1",
"message": "ok",
"status": "succeeded",
"words_result_num": 0
});
assert!(serde_json::from_value::<OcrResponse>(valid).is_ok());
assert!(serde_json::from_str::<OcrResponse>("{}").is_err());
assert!(
serde_json::from_value::<OcrResponse>(serde_json::json!({
"task_id": "ocr-1",
"message": "ok",
"status": "SUCCESS",
"words_result_num": 0
}))
.is_err()
);
}
#[test]
fn result_item_enforces_nested_required_fields() {
assert!(serde_json::from_str::<WordsResultItem>(r#"{"words":"hello"}"#).is_err());
let item = serde_json::json!({
"location": {"left": 1, "top": 2, "width": 3, "height": 4},
"words": "hello",
"probability": {"average": 0.9, "variance": 0.1, "min": 0.7}
});
assert!(serde_json::from_value::<WordsResultItem>(item).is_ok());
}
}