Skip to main content

kernaux_sys/
assert.rs

1use libc::{c_char, c_int};
2
3pub type AssertCB = unsafe extern "C" fn(*const c_char, c_int, *const c_char);
4
5#[link(name = "kernaux")]
6extern "C" {
7    #[link_name = "kernaux_assert_do"]
8    pub fn assert_do(file: *const c_char, line: c_int, msg: *const c_char);
9
10    #[link_name = "kernaux_assert_cb"]
11    pub static mut assert_cb: Option<AssertCB>;
12}
13
14#[cfg(test)]
15mod tests {
16    use super::*;
17
18    use std::ffi::{CStr, CString};
19    use std::ptr::null;
20
21    static mut LAST_FILE: *const c_char = null();
22    static mut LAST_LINE: c_int = 0;
23    static mut LAST_MSG: *const c_char = null();
24
25    unsafe extern "C" fn some_assert_cb(
26        file: *const c_char,
27        line: c_int,
28        msg: *const c_char,
29    ) {
30        LAST_FILE = file;
31        LAST_LINE = line;
32        LAST_MSG = msg;
33    }
34
35    #[test]
36    fn default() {
37        unsafe {
38            assert_cb = None;
39            assert!(assert_cb.is_none());
40
41            assert_cb = Some(some_assert_cb);
42            match assert_cb {
43                None => panic!(),
44                Some(actual_assert_cb) => {
45                    assert!(actual_assert_cb == some_assert_cb)
46                }
47            }
48
49            let file_cstr = CString::new("foo.rs").unwrap();
50            let msg_cstr = CString::new("bar").unwrap();
51
52            assert_do(
53                file_cstr.as_ptr() as *const c_char,
54                123,
55                msg_cstr.as_ptr() as *const c_char,
56            );
57
58            let file = CStr::from_ptr(LAST_FILE).to_str().unwrap();
59            let line = LAST_LINE;
60            let msg = CStr::from_ptr(LAST_MSG).to_str().unwrap();
61
62            assert_eq!(file, "foo.rs");
63            assert_eq!(line, 123);
64            assert_eq!(msg, "bar");
65        }
66    }
67}