Files
wifi-densepose/vendor/ruvector/examples/scipix/src/api/requests.rs

228 lines
5.5 KiB
Rust

use serde::{Deserialize, Serialize};
use validator::Validate;
/// Text/Image OCR request
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct TextRequest {
/// Image source (base64, URL, or multipart)
#[serde(skip_serializing_if = "Option::is_none")]
pub src: Option<String>,
/// Base64 encoded image data
#[serde(skip_serializing_if = "Option::is_none")]
pub base64: Option<String>,
/// Image URL
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(url)]
pub url: Option<String>,
/// Request metadata
#[serde(default)]
pub metadata: RequestMetadata,
}
impl TextRequest {
/// Get image data from request
pub async fn get_image_data(&self) -> anyhow::Result<Vec<u8>> {
if let Some(base64_data) = &self.base64 {
// Decode base64
use base64::Engine;
let decoded = base64::engine::general_purpose::STANDARD.decode(base64_data)?;
Ok(decoded)
} else if let Some(url) = &self.url {
// Download from URL
let response = reqwest::get(url).await?;
let bytes = response.bytes().await?;
Ok(bytes.to_vec())
} else {
anyhow::bail!("No image data provided")
}
}
}
/// Digital ink strokes request
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct StrokesRequest {
/// Array of stroke data
#[validate(length(min = 1))]
pub strokes: Vec<Stroke>,
/// Request metadata
#[serde(default)]
pub metadata: RequestMetadata,
}
/// Single stroke in digital ink
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Stroke {
/// X coordinates
pub x: Vec<f64>,
/// Y coordinates
pub y: Vec<f64>,
/// Optional timestamps
#[serde(skip_serializing_if = "Option::is_none")]
pub t: Option<Vec<f64>>,
}
/// Legacy LaTeX equation request
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct LatexRequest {
/// Image source
#[serde(skip_serializing_if = "Option::is_none")]
pub src: Option<String>,
/// Base64 encoded image
#[serde(skip_serializing_if = "Option::is_none")]
pub base64: Option<String>,
/// Image URL
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(url)]
pub url: Option<String>,
/// Request metadata
#[serde(default)]
pub metadata: RequestMetadata,
}
/// PDF processing request
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
pub struct PdfRequest {
/// PDF file URL
#[validate(url)]
pub url: String,
/// Conversion options
#[serde(default)]
pub options: PdfOptions,
/// Webhook URL for completion notification
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(url)]
pub webhook_url: Option<String>,
/// Request metadata
#[serde(default)]
pub metadata: RequestMetadata,
}
/// PDF processing options
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PdfOptions {
/// Output format
#[serde(default = "default_format")]
pub format: String,
/// Enable OCR
#[serde(default)]
pub enable_ocr: bool,
/// Include images
#[serde(default = "default_true")]
pub include_images: bool,
/// Page range (e.g., "1-5")
#[serde(skip_serializing_if = "Option::is_none")]
pub page_range: Option<String>,
}
fn default_format() -> String {
"mmd".to_string()
}
fn default_true() -> bool {
true
}
/// Request metadata
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct RequestMetadata {
/// Output formats
#[serde(default = "default_formats")]
pub formats: Vec<String>,
/// Include confidence scores
#[serde(default)]
pub include_confidence: bool,
/// Enable math mode
#[serde(default = "default_true")]
pub enable_math: bool,
/// Language hint
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
}
fn default_formats() -> Vec<String> {
vec!["text".to_string()]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_text_request_validation() {
let request = TextRequest {
src: None,
base64: Some("SGVsbG8gV29ybGQ=".to_string()),
url: None,
metadata: RequestMetadata::default(),
};
assert!(request.validate().is_ok());
}
#[test]
fn test_strokes_request_validation() {
let request = StrokesRequest {
strokes: vec![Stroke {
x: vec![0.0, 1.0, 2.0],
y: vec![0.0, 1.0, 0.0],
t: None,
}],
metadata: RequestMetadata::default(),
};
assert!(request.validate().is_ok());
}
#[test]
fn test_empty_strokes_validation() {
let request = StrokesRequest {
strokes: vec![],
metadata: RequestMetadata::default(),
};
assert!(request.validate().is_err());
}
#[test]
fn test_pdf_request_validation() {
let request = PdfRequest {
url: "https://example.com/document.pdf".to_string(),
options: PdfOptions::default(),
webhook_url: None,
metadata: RequestMetadata::default(),
};
assert!(request.validate().is_ok());
}
#[test]
fn test_invalid_url() {
let request = PdfRequest {
url: "not-a-url".to_string(),
options: PdfOptions::default(),
webhook_url: None,
metadata: RequestMetadata::default(),
};
assert!(request.validate().is_err());
}
}