diff --git a/Cargo.lock b/Cargo.lock index 188fe74..7fd332f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,203 +2,22 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "cc" -version = "1.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" -dependencies = [ - "shlex", -] - -[[package]] -name = "gettext-rs" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44e92f7dc08430aca7ed55de161253a22276dfd69c5526e5c5e95d1f7cf338a" -dependencies = [ - "gettext-sys", - "locale_config", -] - -[[package]] -name = "gettext-sys" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb45773f5b8945f12aecd04558f545964f943dacda1b1155b3d738f5469ef661" -dependencies = [ - "cc", - "temp-dir", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "locale_config" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" -dependencies = [ - "lazy_static", - "objc", - "objc-foundation", - "regex", - "winapi", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - [[package]] name = "regex-rs" version = "0.1.0" dependencies = [ "bitflags", - "gettext-rs", - "libc", - "strprintf", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "strprintf" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8beb19b8073c6b7cd9be277ff8e6d975eece17b078d5e0b70e31ca15202c178" -dependencies = [ "libc", ] - -[[package]] -name = "temp-dir" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 7ef1251..207550d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,5 @@ categories = ["api-bindings", "os"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -strprintf = "0.1.0" - bitflags = "2.6" libc = ">=0.2.69" -gettext-rs = "0.7.2" diff --git a/src/lib.rs b/src/lib.rs index 89f2b3b..896f487 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,13 +34,11 @@ #![allow(clippy::unreadable_literal)] use bitflags::bitflags; -use gettextrs::gettext; use libc::{regcomp, regerror, regex_t, regexec, regfree, regmatch_t}; use std::ffi::{CString, OsString}; use std::mem; use std::os::unix::ffi::OsStringExt; use std::ptr; -use strprintf::fmt; /// POSIX regular expression. pub struct Regex { @@ -114,7 +112,7 @@ pub struct Match { } /// A wrapper around `libc::regerror()`. -unsafe fn regex_error_to_str(errcode: libc::c_int, regex: ®ex_t) -> Option { +unsafe fn regex_error_to_str(errcode: libc::c_int, regex: ®ex_t) -> OsString { // Find out the size of the buffer needed to hold the error message let errmsg_length = regerror(errcode, regex, ptr::null_mut(), 0); @@ -132,7 +130,106 @@ unsafe fn regex_error_to_str(errcode: libc::c_int, regex: ®ex_t) -> Option Result { - let pattern = CString::new(pattern) - .map_err(|_| String::from("Regular expression contains NUL byte"))?; + pub fn new(pattern: &str, flags: CompFlags) -> Result { + let pattern = CString::new(pattern).or(Err(CompError::InputContainsNul))?; unsafe { let mut regex: regex_t = mem::zeroed(); @@ -156,15 +252,10 @@ impl Regex { if errcode == 0 { Ok(Regex { regex }) } else { - match regex_error_to_str(errcode, ®ex) { - Some(regcomp_errmsg) => { - let msg = fmt!(&gettext("regcomp returned code %i"), errcode); - let msg = format!("{msg}: {regcomp_errmsg}"); - Err(msg) - } - - None => Err(fmt!(&gettext("regcomp returned code %i"), errcode)), - } + Err(CompError::RegcompError { + code: errcode, + message: regex_error_to_str(errcode, ®ex), + }) } } } @@ -175,7 +266,7 @@ impl Regex { /// `max_matches`-1 of those. First match is reserved for the text that the whole regex /// matched. /// - /// `flags` dictate how matching is performed. See `MatchFlags` for details. + /// `flags` dictate how matching is performed. See [`MatchFlags`][] for details. /// /// # Returns /// @@ -190,9 +281,8 @@ impl Regex { input: &str, max_matches: usize, flags: MatchFlags, - ) -> Result, String> { - let input = - CString::new(input).map_err(|_| String::from("Input string contains NUL byte"))?; + ) -> Result, MatchError> { + let input = CString::new(input).or(Err(MatchError::InputContainsNul))?; let mut pmatch: Vec; @@ -241,14 +331,10 @@ impl Regex { // POSIX only specifies two return codes for regexec(), but implementations are free to // extend that. _ => unsafe { - match regex_error_to_str(errcode, &self.regex) { - Some(regexec_errmsg) => { - let msg = fmt!(&gettext("regexec returned code %i"), errcode); - let msg = format!("{msg}: {regexec_errmsg}"); - Err(msg) - } - None => Err(fmt!(&gettext("regexec returned code %i"), errcode)), - } + Err(MatchError::RegexecError { + code: errcode, + message: regex_error_to_str(errcode, &self.regex), + }) }, } } @@ -334,13 +420,15 @@ mod tests { fn new_returns_error_on_invalid_regex() { let result = Regex::new("(abc", CompFlags::EXTENDED); - assert!(result.is_err()); - if let Err(msg) = result { - // There should be at least an error code, so string can't possibly be empty - assert!(!msg.is_empty()); + match result { + Err(CompError::RegcompError { code, message }) => { + assert_eq!(code, ErrCode::EPAREN as i32); + // There should be a message when there is an error. + assert!(!message.is_empty()); + } - // The message shouldn't contain a C string terminator (NUL) at the end - assert!(!msg.ends_with('\0')); + Ok(_) => panic!("Regex::new() returned Ok(), expected Err()"), + Err(e) => panic!("Regex::new() returned an unexpected value: Err({:?})", e), } } }