use crate::cleaner::clean;
use crate::unicode::{CleanOpts, InspectOpts, clean_text, inspect_text};
use napi::bindgen_prelude::*;
use napi_derive::napi;
#[napi(object)]
pub struct CleanTextResult {
pub cleaned: String,
pub removed_count: u32,
pub replaced_count: u32,
pub summary: Vec<String>,
}
#[napi(object)]
pub struct CharHit {
pub codepoint: u32,
pub character: String,
pub label: String,
pub count: u32,
pub kind: String,
pub confidence: String,
pub sample_offsets: Vec<u32>,
}
#[napi(object)]
pub struct TextInspectReport {
pub length: u32,
pub suspicious_total: u32,
pub hits: Vec<CharHit>,
pub notes: Vec<String>,
}
#[napi(js_name = "cleanText")]
pub fn clean_text_node(text: String) -> napi::Result<CleanTextResult> {
let opts = CleanOpts::safe();
let (cleaned, stats) =
clean_text(&text, &opts).map_err(|e| napi::Error::from_reason(e.to_string()))?;
Ok(CleanTextResult {
cleaned,
removed_count: stats.removed_count as u32,
replaced_count: stats.replaced_count as u32,
summary: stats.summary,
})
}
#[napi(js_name = "inspectText")]
pub fn inspect_text_node(text: String) -> napi::Result<TextInspectReport> {
let opts = InspectOpts::default();
let report = inspect_text(&text, &opts).map_err(|e| napi::Error::from_reason(e.to_string()))?;
let hits = report
.hits
.into_iter()
.map(|h| CharHit {
codepoint: h.codepoint,
character: h.character,
label: h.label,
count: h.count as u32,
kind: h.kind.as_str().to_string(),
confidence: h.confidence.as_str().to_string(),
sample_offsets: h.sample_offsets.into_iter().map(|o| o as u32).collect(),
})
.collect();
Ok(TextInspectReport {
length: report.length as u32,
suspicious_total: report.suspicious_total as u32,
hits,
notes: report.notes,
})
}
#[napi(js_name = "cleanBytes")]
pub fn clean_bytes_node(data: Buffer) -> napi::Result<Buffer> {
let bytes: &[u8] = &data;
let out = clean(bytes, None).map_err(|e| napi::Error::from_reason(e.to_string()))?;
Ok(Buffer::from(out.bytes))
}