1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// ```
/// use itex2mml::*;
/// let formula = MML::parse(r#"$\int_a^b x\mathrm{d}x$"#).unwrap();
/// formula.as_str();
/// ```
use libc::*;
use std::ffi::CStr;

#[link(name = "itex2mml")]
extern "C" {
    fn itex2MML_parse(buffer: *const c_char, len: size_t) -> *mut c_char;
    fn itex2MML_free_string(ptr: *const c_char);
}

pub struct MML {
    p: *mut c_char,
}

impl MML {
    /// Parses the argument, and returns a newly allocated string
    /// containing the result.
    pub fn parse(s: &str) -> Option<Self> {
        unsafe {
            let p = itex2MML_parse(s.as_ptr() as *const c_char, s.len() as size_t);
            if p.is_null() {
                None
            } else {
                Some(MML { p })
            }
        }
    }
    pub fn as_cstr(&self) -> &CStr {
        unsafe { CStr::from_ptr(self.p) }
    }
    pub fn as_str(&self) -> &str {
        unsafe { std::str::from_utf8_unchecked(self.as_cstr().to_bytes()) }
    }
}

impl Drop for MML {
    fn drop(&mut self) {
        unsafe { itex2MML_free_string(self.p) }
    }
}