rust/hg-core/src/re2/re2.rs
author Raphaël Gomès <rgomes@octobus.net>
Thu, 16 Jan 2020 13:34:04 +0100
changeset 44305 d8d4fa9a7f18
permissions -rw-r--r--
rust-re2: add wrapper for calling Re2 from Rust This assumes that Re2 is installed following Google's guide. I am not sure how we want to integrate it in the project, but I think a follow-up patch would be more appropriate for such work. As it stands, *not* having Re2 installed results in a compilation error, which is a problem as it breaks install compatibility. Hence, this is gated behind a non-default `with-re2` compilation feature. Differential Revision: https://phab.mercurial-scm.org/D7910
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
44305
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
/*
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
re2.rs
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
Rust FFI bindings to Re2.
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
Copyright 2020 Valentin Gatien-Baron
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
This software may be used and distributed according to the terms of the
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
GNU General Public License version 2 or any later version.
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
*/
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
use libc::{c_int, c_void};
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    12
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    13
type Re2Ptr = *const c_void;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    14
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    15
pub struct Re2(Re2Ptr);
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    16
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    17
/// `re2.h` says:
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    18
/// "An "RE2" object is safe for concurrent use by multiple threads."
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
unsafe impl Sync for Re2 {}
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
/// These bind to the C ABI in `rust_re2.cpp`.
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
extern "C" {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
    fn rust_re2_create(data: *const u8, len: usize) -> Re2Ptr;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
    fn rust_re2_destroy(re2: Re2Ptr);
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
    fn rust_re2_ok(re2: Re2Ptr) -> bool;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
    fn rust_re2_error(
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
        re2: Re2Ptr,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
        outdata: *mut *const u8,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
        outlen: *mut usize,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
    ) -> bool;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
    fn rust_re2_match(
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
        re2: Re2Ptr,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
        data: *const u8,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
        len: usize,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
        anchor: c_int,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
    ) -> bool;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
}
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
impl Re2 {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
    pub fn new(pattern: &[u8]) -> Result<Re2, String> {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
        unsafe {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
            let re2 = rust_re2_create(pattern.as_ptr(), pattern.len());
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
            if rust_re2_ok(re2) {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
                Ok(Re2(re2))
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
            } else {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
                let mut data: *const u8 = std::ptr::null();
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
                let mut len: usize = 0;
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
                rust_re2_error(re2, &mut data, &mut len);
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
                Err(String::from_utf8_lossy(std::slice::from_raw_parts(
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
                    data, len,
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
                ))
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
                .to_string())
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
            }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    54
        }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
    }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
    pub fn is_match(&self, data: &[u8]) -> bool {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
        unsafe { rust_re2_match(self.0, data.as_ptr(), data.len(), 1) }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
    }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
}
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    61
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
impl Drop for Re2 {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
    fn drop(&mut self) {
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    64
        unsafe { rust_re2_destroy(self.0) }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
    }
d8d4fa9a7f18 rust-re2: add wrapper for calling Re2 from Rust
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
}