use wasm_bindgen::prelude::*;
use crate::convert_bytes;
use crate::converter::{ConversionOptions, ConversionResult};
#[wasm_bindgen(js_name = "convertBytes")]
pub fn convert_bytes_wasm(data: &[u8], extension: &str) -> Result<JsValue, JsError> {
let options = ConversionOptions::default();
let result =
convert_bytes(data, extension, &options).map_err(|e| JsError::new(&e.to_string()))?;
convert_result_to_js(&result)
}
#[wasm_bindgen(js_name = "convertBytesWithOptions")]
pub fn convert_bytes_with_options_wasm(
data: &[u8],
extension: &str,
strict: bool,
) -> Result<JsValue, JsError> {
let options = ConversionOptions {
strict,
..Default::default()
};
let result =
convert_bytes(data, extension, &options).map_err(|e| JsError::new(&e.to_string()))?;
convert_result_to_js(&result)
}
#[cfg(feature = "async-gemini")]
#[wasm_bindgen(js_name = "convertBytesWithGemini")]
pub async fn convert_bytes_with_gemini_wasm(
data: &[u8],
extension: &str,
api_key: &str,
model: Option<String>,
) -> Result<JsValue, JsError> {
use std::sync::Arc;
use crate::convert_bytes_async;
use crate::converter::AsyncConversionOptions;
use crate::gemini::AsyncGeminiDescriber;
let describer = match model {
Some(m) => AsyncGeminiDescriber::new(api_key.to_string()).with_model(m),
None => AsyncGeminiDescriber::new(api_key.to_string()),
};
let options = AsyncConversionOptions {
async_image_describer: Some(Arc::new(describer)),
..Default::default()
};
let result = convert_bytes_async(data, extension, &options)
.await
.map_err(|e| JsError::new(&e.to_string()))?;
convert_result_to_js(&result)
}
fn convert_result_to_js(result: &ConversionResult) -> Result<JsValue, JsError> {
let obj = js_sys::Object::new();
js_sys::Reflect::set(&obj, &"markdown".into(), &result.markdown.as_str().into())
.map_err(|_| JsError::new("failed to set markdown property"))?;
js_sys::Reflect::set(
&obj,
&"plainText".into(),
&result.plain_text.as_str().into(),
)
.map_err(|_| JsError::new("failed to set plainText property"))?;
js_sys::Reflect::set(
&obj,
&"title".into(),
&match result.title {
Some(ref t) => JsValue::from_str(t),
None => JsValue::NULL,
},
)
.map_err(|_| JsError::new("failed to set title property"))?;
let warnings_arr = js_sys::Array::new();
for w in &result.warnings {
let msg = match &w.location {
Some(loc) => format!("[{:?}] {} ({})", w.code, w.message, loc),
None => format!("[{:?}] {}", w.code, w.message),
};
warnings_arr.push(&msg.into());
}
js_sys::Reflect::set(&obj, &"warnings".into(), &warnings_arr.into())
.map_err(|_| JsError::new("failed to set warnings property"))?;
Ok(obj.into())
}