bibutils_sys/
lib.rs

1#[allow(warnings)]
2mod ffi;
3
4pub use self::ffi::*;
5
6#[cfg(test)]
7mod tests {
8    use super::{
9        bibl_free, bibl_freeparams, bibl_init, bibl_initparams, bibl_read, bibl_write, fopen,
10        BIBL_BIBTEXIN, BIBL_OK, BIBL_RISOUT,
11    };
12    use indoc::indoc;
13    use std::{ffi::CString, fs, mem::MaybeUninit};
14    use tempfile::tempdir;
15
16    #[test]
17    fn bibtex_to_ris() {
18        unsafe {
19            let mut context = MaybeUninit::zeroed();
20            bibl_init(context.as_mut_ptr());
21
22            let mut params = MaybeUninit::zeroed();
23            let program = CString::new("bibutils-sys").unwrap();
24            bibl_initparams(
25                params.as_mut_ptr(),
26                BIBL_BIBTEXIN as i32,
27                BIBL_RISOUT as i32,
28                program.as_ptr() as *mut i8,
29            );
30
31            let dir = tempdir().unwrap();
32            let input_path = dir.path().join("references.bib");
33            fs::write(
34                &input_path,
35                indoc!(
36                    r#"
37                        @article{foo,
38                            author = {Foo Bar},
39                            title = {Baz Qux},
40                            year = 2020
41                        }
42                    "#
43                ),
44            )
45            .unwrap();
46
47            let input_path = CString::new(input_path.to_str().unwrap()).unwrap();
48            let input_mode = CString::new("r").unwrap();
49            let input_handle = fopen(input_path.as_ptr(), input_mode.as_ptr());
50            let status = bibl_read(
51                context.as_mut_ptr(),
52                input_handle,
53                input_path.as_ptr() as *mut i8,
54                params.as_mut_ptr(),
55            );
56            assert_eq!(status, BIBL_OK as i32);
57
58            let output_path = dir.path().join("references.ris");
59            let output_path = CString::new(output_path.to_str().unwrap()).unwrap();
60            let output_mode = CString::new("w").unwrap();
61            let output_handle = fopen(output_path.as_ptr(), output_mode.as_ptr());
62            let status = bibl_write(context.as_mut_ptr(), output_handle, params.as_mut_ptr());
63            assert_eq!(status, BIBL_OK as i32);
64
65            let data = fs::read(dir.path().join("references.ris")).unwrap();
66            let text = String::from_utf8_lossy(&data[3..]).into_owned();
67
68            bibl_freeparams(params.as_mut_ptr());
69            bibl_free(context.as_mut_ptr());
70
71            println!("{}", text);
72            assert_eq!(
73                text.trim().replace("\r\n", "\n"),
74                indoc!(
75                    r#"
76                        TY  - JOUR
77                        AU  - Bar, Foo
78                        PY  - 2020
79                        DA  - 2020//
80                        TI  - Baz Qux
81                        ID  - foo
82                        ER  -
83                    "#
84                )
85                .trim()
86            );
87        }
88    }
89}