alef 0.62.8

Opinionated polyglot binding generator for Rust libraries
Documentation
// WASM environment shims for C scanner interop
#[cfg(target_arch = "wasm32")]
mod alef_wasm_env_shims {
{% for name in shims %}
{% if name == "memchr" %}
    /// # Safety
    /// Caller must ensure `s` points to a buffer of at least `n` bytes.
    #[unsafe(no_mangle)]
    pub unsafe extern "C" fn memchr(s: *const u8, c: i32, n: usize) -> *const u8 {
        if s.is_null() { return core::ptr::null(); }
        let needle = c as u8;
        let slice = unsafe { core::slice::from_raw_parts(s, n) };
        match slice.iter().position(|&byte| byte == needle) {
            Some(index) => unsafe { s.add(index) },
            None => core::ptr::null(),
        }
    }
{% elif name == "strcmp" %}
    /// # Safety
    /// Caller must ensure both pointers are valid null-terminated C strings.
    #[unsafe(no_mangle)]
    pub unsafe extern "C" fn strcmp(a: *const u8, b: *const u8) -> i32 {
        if a.is_null() || b.is_null() { return 0; }
        let mut index = 0isize;
        loop {
            let left = unsafe { *a.offset(index) };
            let right = unsafe { *b.offset(index) };
            if left != right { return (left as i32) - (right as i32); }
            if left == 0 { return 0; }
            index += 1;
        }
    }
{% elif name == "towupper" %}
    #[unsafe(no_mangle)]
    pub extern "C" fn towupper(c: u32) -> u32 {
        char::from_u32(c).map_or(c, |ch| ch.to_uppercase().next().unwrap_or(ch) as u32)
    }
{% elif name == "towlower" %}
    #[unsafe(no_mangle)]
    pub extern "C" fn towlower(c: u32) -> u32 {
        char::from_u32(c).map_or(c, |ch| ch.to_lowercase().next().unwrap_or(ch) as u32)
    }
{% else %}
    #[unsafe(no_mangle)]
    pub extern "C" fn {{ name }}(c: u32) -> i32 {
{% if name == "iswspace" %}
        char::from_u32(c).map_or(0, |ch| ch.is_whitespace() as i32)
{% elif name == "iswalnum" %}
        char::from_u32(c).map_or(0, |ch| ch.is_alphanumeric() as i32)
{% elif name == "iswalpha" %}
        char::from_u32(c).map_or(0, |ch| ch.is_alphabetic() as i32)
{% elif name == "iswlower" %}
        char::from_u32(c).map_or(0, |ch| ch.is_lowercase() as i32)
{% elif name == "iswupper" %}
        char::from_u32(c).map_or(0, |ch| ch.is_uppercase() as i32)
{% elif name == "iswxdigit" %}
        char::from_u32(c).map_or(0, |ch| ch.is_ascii_hexdigit() as i32)
{% endif %}
    }
{% endif %}
{% endfor %}
}