/* re2.rs Rust FFI bindings to Re2. Copyright 2020 Valentin Gatien-Baron This software may be used and distributed according to the terms of the GNU General Public License version 2 or any later version. */ use libc::{c_int, c_void}; type Re2Ptr = *const c_void; pub struct Re2(Re2Ptr); /// `re2.h` says: /// "An "RE2" object is safe for concurrent use by multiple threads." unsafe impl Sync for Re2 {} /// These bind to the C ABI in `rust_re2.cpp`. extern "C" { fn rust_re2_create(data: *const u8, len: usize) -> Re2Ptr; fn rust_re2_destroy(re2: Re2Ptr); fn rust_re2_ok(re2: Re2Ptr) -> bool; fn rust_re2_error( re2: Re2Ptr, outdata: *mut *const u8, outlen: *mut usize, ) -> bool; fn rust_re2_match( re2: Re2Ptr, data: *const u8, len: usize, anchor: c_int, ) -> bool; } impl Re2 { pub fn new(pattern: &[u8]) -> Result { unsafe { let re2 = rust_re2_create(pattern.as_ptr(), pattern.len()); if rust_re2_ok(re2) { Ok(Re2(re2)) } else { let mut data: *const u8 = std::ptr::null(); let mut len: usize = 0; rust_re2_error(re2, &mut data, &mut len); Err(String::from_utf8_lossy(std::slice::from_raw_parts( data, len, )) .to_string()) } } } pub fn is_match(&self, data: &[u8]) -> bool { unsafe { rust_re2_match(self.0, data.as_ptr(), data.len(), 1) } } } impl Drop for Re2 { fn drop(&mut self) { unsafe { rust_re2_destroy(self.0) } } }