use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[wasm_bindgen]
pub struct OcrResult {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub latex: Option<String>,
pub confidence: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<serde_json::Value>,
}
#[wasm_bindgen]
impl OcrResult {
#[wasm_bindgen(constructor)]
pub fn new(text: String, confidence: f32) -> Self {
Self {
text,
latex: None,
confidence,
metadata: None,
}
}
#[wasm_bindgen(getter)]
pub fn text(&self) -> String {
self.text.clone()
}
#[wasm_bindgen(getter)]
pub fn latex(&self) -> Option<String> {
self.latex.clone()
}
#[wasm_bindgen(getter)]
pub fn confidence(&self) -> f32 {
self.confidence
}
#[wasm_bindgen(js_name = hasLatex)]
pub fn has_latex(&self) -> bool {
self.latex.is_some()
}
#[wasm_bindgen(js_name = toJSON)]
pub fn to_json(&self) -> Result<JsValue, JsValue> {
serde_wasm_bindgen::to_value(self)
.map_err(|e| JsValue::from_str(&format!("Serialization failed: {}", e)))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RecognitionFormat {
Text,
Latex,
Both,
}
impl RecognitionFormat {
pub fn to_string(&self) -> String {
match self {
Self::Text => "text".to_string(),
Self::Latex => "latex".to_string(),
Self::Both => "both".to_string(),
}
}
}
impl Default for RecognitionFormat {
fn default() -> Self {
Self::Both
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[wasm_bindgen]
pub struct ProcessingOptions {
pub format: String,
pub confidence_threshold: f32,
pub preprocess: bool,
pub postprocess: bool,
}
#[wasm_bindgen]
impl ProcessingOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
#[wasm_bindgen(js_name = setFormat)]
pub fn set_format(&mut self, format: String) {
self.format = format;
}
#[wasm_bindgen(js_name = setConfidenceThreshold)]
pub fn set_confidence_threshold(&mut self, threshold: f32) {
self.confidence_threshold = threshold;
}
}
impl Default for ProcessingOptions {
fn default() -> Self {
Self {
format: "both".to_string(),
confidence_threshold: 0.5,
preprocess: true,
postprocess: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WasmError {
ImageDecode(String),
Processing(String),
InvalidInput(String),
NotInitialized,
}
impl std::fmt::Display for WasmError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ImageDecode(msg) => write!(f, "Image decode error: {}", msg),
Self::Processing(msg) => write!(f, "Processing error: {}", msg),
Self::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
Self::NotInitialized => write!(f, "WASM module not initialized"),
}
}
}
impl std::error::Error for WasmError {}
impl From<WasmError> for JsValue {
fn from(error: WasmError) -> Self {
JsValue::from_str(&error.to_string())
}
}