Compare commits

..

No commits in common. '007ba8781cd4448f0c7a5b9a696d7367cf882dba' and 'd9ad1bafdfde1ce60621c2be710716283b9379b1' have entirely different histories.

@ -1,29 +1,20 @@
[package]
name = "rematch"
version = "0.2.0"
version = "0.1.0"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2024"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
opt-level = 3
lto = true
lto = "fat"
codegen-units = 1
panic = "unwind"
strip = true
[profile.symbols]
inherits = "release"
strip = false
[features]
default= ["perl", "unstable"]
perl = ["dep:pcre2"]
unstable = ["regex/unstable"]
perl = ["pcre"]
[dependencies]
pcre2 = { version = "0.2.9", optional = true }
regex = { version = "1.11.1", features = ["use_std"] }
color-eyre = { version = "0.6.3", default-features = false, features = ["track-caller"] }
regex = "1"
pcre = { version = "0.2.3", optional = true }

@ -3,42 +3,8 @@
mod re;
mod text;
use color_eyre::{
eyre::{
self,
eyre,
WrapErr as _,
},
SectionExt as _, Help as _,
};
fn initialise() -> eyre::Result<()>
{
color_eyre::install()?;
Ok(())
}
fn print_group<S: ?Sized, G, T>(to: &mut S, g: G, group: usize) -> std::io::Result<()>
where S: std::io::Write,
G: IntoIterator<Item = Option<T>>,
T: std::borrow::Borrow<str>
{
match g.into_iter().nth(group) {
Some(None) => writeln!(to, ""),
Some(Some(g)) => writeln!(to, "{}", g.borrow()),
None => Ok(()),
}
}
fn main() -> eyre::Result<()>
fn main() -> Result<(), Box<dyn std::error::Error>>
{
initialise().wrap_err("Fatal: Failed to install panic handle")?;
// let cli = args::parse_cli();//.wrap_err("Error parsing command-line arguments")?;
//
// eprintln!("{:#?}", cli);
// return Ok(());
let args: Vec<String> = std::env::args().collect();
if args.len() < 4 {
@ -50,14 +16,10 @@ fn main() -> eyre::Result<()>
let text = &args[1];
let group: usize = args[3].parse().expect("Invalid group number.");
use std::io::Write;
let mut stdout = std::io::stdout();
if text == "-" {
text::stdin_lines(|text| -> eyre::Result<bool> {
let mut stdout = stdout.lock();
text::stdin_lines(|text| -> Result<bool, re::Error> {
match re.exec(&text)? {
Some(g) if g.len() > group => print_group(&mut stdout, g, group)?, //println!("{}", &g[group]),
Some(g) if g.len() > group => println!("{}", &g[group]),
_ => (),
}
Ok(true)
@ -65,11 +27,10 @@ fn main() -> eyre::Result<()>
} else {
match re.exec(&text)? {
Some(g) if g.len() > group => print_group(&mut stdout, g, group)?,//println!("{}", &g.nth(group).unwrap().map(|x| x.as_ref()).unwrap_or("")),
Some(g) if g.len() > group => println!("{}", &g[group]),
_ => (),
}
}
stdout.flush().unwrap();
}
Ok(())
}

@ -1,23 +1,23 @@
#![allow(unused_imports)]
use std::{
error,
fmt,
borrow::Cow,
fmt::{
self,
Write,
},
sync::{
Arc,
Mutex,
}
};
pub type FrozenVec<T> = Box<[T]>;
pub type FrozenString = Box<str>;
// NOTE: Currently unused, as we use `to_utf8_lossy()` for PCRE2 `byte`-matching (XXX: Should we change?)
// TODO: to return some kind of `Either<&'s str, impl bytes::Buf + 's>` type, which would use `str` on non-PCRE, but opaque `bytes::Buf` on PCRE?)
pub type FrozenBytes = FrozenVec<u8>;
pub type Groups = Vec<String>;
pub type Groups<String = FrozenString> = FrozenVec<Option<String>>;
#[derive(Debug, Clone)]
pub struct Regex
{
#[cfg(feature="perl")]
internal: pcre2::bytes::Regex,
internal: Arc<Mutex<pcre::Pcre>>,
#[cfg(not(feature = "perl"))]
internal: regex::Regex,
}
@ -50,18 +50,24 @@ impl Regex {
pub fn compile(string: impl AsRef<str>) -> Result<Self, Error>
{
#[cfg(feature = "perl")]
return Ok(Self{internal: pcre2::bytes::RegexBuilder::new().build(string.as_ref())?});
return Ok(Self{internal: Arc::new(Mutex::new(pcre::Pcre::compile(string.as_ref())?))});
#[cfg(not(feature = "perl"))]
return Ok(Self{internal: regex::Regex::new(string.as_ref())?});
}
pub fn exec<'s>(&self, string: &'s str) -> Result<Option<Groups<Cow<'s, str>>>, Error>
pub fn exec(&self, string: impl AsRef<str>) -> Result<Option<Groups>, Error>
{
#[cfg(feature = "perl")]
return {
Ok(match self.internal.captures(string.as_ref())? {
let mut re = self.internal.lock().unwrap();
Ok(match re.exec(string.as_ref()) {
Some(m) => {
Some((0..m.len()).map(move |i| m.get(i).map(|x| String::from_utf8_lossy(x.as_bytes()) )).collect())
let len = m.string_count();
let mut output = Vec::with_capacity(len);
for i in 0..len {
output.push(m.group(i).to_owned());
}
Some(output)
},
None => None,
})
@ -70,7 +76,14 @@ impl Regex {
return {
Ok(match self.internal.captures(string.as_ref()) {
Some(m) => {
Some((0..m.len()).map(move |i| m.get(i).map(|x| Cow::Borrowed(x.as_str()) )).collect())
let mut output = Vec::with_capacity(m.len());
for i in 0..m.len() {
let ma = m.get(i).unwrap();
let mut op = String::with_capacity(ma.range().len());
write!(op, "{}", ma.as_str())?;
output.push(op);
}
Some(output)
},
None => None,
})
@ -86,7 +99,7 @@ impl From<fmt::Error> for Error
}
}
//#[cfg(not(feature = "perl"))]
#[cfg(not(feature = "perl"))]
impl From<regex::Error> for Error
{
fn from(er: regex::Error) -> Self
@ -96,9 +109,9 @@ impl From<regex::Error> for Error
}
#[cfg(feature = "perl")]
impl From<pcre2::Error> for Error
impl From<pcre::CompilationError> for Error
{
fn from(er: pcre2::Error) -> Self
fn from(er: pcre::CompilationError) -> Self
{
Self::Compile(format!("{}", er))
}

Loading…
Cancel
Save