1use std::ffi::c_void;
2use std::ffi::CStr;
3
4type BoxError = Box<dyn std::error::Error>;
5
6pub struct Dictionary(*const i8);
7
8impl Dictionary {
9 pub fn as_bytes(&self) -> &[u8] {
10 let s = unsafe { CStr::from_ptr(self.0 as *mut i8) };
11 s.to_bytes()
12 }
13}
14
15impl Drop for Dictionary {
16 fn drop(&mut self) {
17 unsafe {
18 brotli_dict_gen_sys::free_result(self.0 as *mut c_void);
19 }
20 }
21}
22
23pub fn generate_dict_from_files(files: Vec<Vec<u8>>) -> Result<Dictionary, BoxError> {
24 let sample_sizes = files.iter().map(|file| file.len()).collect::<Vec<usize>>();
25 let samples = files
26 .into_iter()
27 .fold(vec![], |acc, file| [acc, file].concat());
28
29 let ret_ptr = unsafe {
32 brotli_dict_gen_sys::generate(samples.as_ptr(), sample_sizes.as_ptr(), sample_sizes.len())
33 };
34
35 Ok(Dictionary(ret_ptr))
36}