spoof.rs

 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}