1//! Crate wrapping what we need from ICU’s C API for JIDs.
2//!
3//! See <http://site.icu-project.org/>
4
5use crate::bindings::{
6 icu_spoof_get_skeleton, icu_spoof_open, icu_spoof_set_checks, UErrorCode, USpoofChecker,
7 U_ZERO_ERROR,
8};
9use crate::error::Error;
10
11/// TODO: spoof checker.
12pub struct SpoofChecker {
13 inner: *mut USpoofChecker,
14}
15
16impl SpoofChecker {
17 /// Create a new SpoofChecker.
18 pub fn new(checks: i32) -> Result<SpoofChecker, UErrorCode> {
19 let mut err: UErrorCode = U_ZERO_ERROR;
20 let inner = unsafe { icu_spoof_open(&mut err) };
21 if err != U_ZERO_ERROR {
22 return Err(err);
23 }
24 unsafe { icu_spoof_set_checks(inner, checks, &mut err) };
25 if err != U_ZERO_ERROR {
26 return Err(err);
27 }
28 Ok(SpoofChecker { inner })
29 }
30
31 /// Transform a string into a skeleton for matching it with other potentially similar strings.
32 pub fn get_skeleton(&self, input: &str) -> Result<String, Error> {
33 let mut err: UErrorCode = U_ZERO_ERROR;
34 let mut dest: Vec<u8> = vec![0u8; 256];
35 let len = unsafe {
36 icu_spoof_get_skeleton(
37 self.inner,
38 0,
39 input.as_ptr(),
40 input.len() as i32,
41 dest.as_mut_ptr(),
42 dest.len() as i32,
43 &mut err,
44 )
45 };
46 if err != U_ZERO_ERROR {
47 return Err(Error::from_icu_code(err));
48 }
49 dest.truncate(len as usize);
50 Ok(String::from_utf8(dest)?)
51 }
52}