Compare commits

..

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

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

@ -3,42 +3,8 @@
mod re; mod re;
mod text; mod text;
use color_eyre::{ fn main() -> Result<(), Box<dyn std::error::Error>>
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<()>
{
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(); let args: Vec<String> = std::env::args().collect();
if args.len() < 4 { if args.len() < 4 {
@ -50,14 +16,10 @@ fn main() -> eyre::Result<()>
let text = &args[1]; let text = &args[1];
let group: usize = args[3].parse().expect("Invalid group number."); let group: usize = args[3].parse().expect("Invalid group number.");
use std::io::Write;
let mut stdout = std::io::stdout();
if text == "-" { if text == "-" {
text::stdin_lines(|text| -> eyre::Result<bool> { text::stdin_lines(|text| -> Result<bool, re::Error> {
let mut stdout = stdout.lock();
match re.exec(&text)? { 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) Ok(true)
@ -65,11 +27,10 @@ fn main() -> eyre::Result<()>
} else { } else {
match re.exec(&text)? { 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(()) Ok(())
} }

@ -1,23 +1,23 @@
#![allow(unused_imports)]
use std::{ use std::{
error, error,
fmt, fmt::{
borrow::Cow, self,
Write,
},
sync::{
Arc,
Mutex,
}
}; };
pub type FrozenVec<T> = Box<[T]>; pub type Groups = Vec<String>;
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<String = FrozenString> = FrozenVec<Option<String>>;
#[derive(Debug, Clone)]
pub struct Regex pub struct Regex
{ {
#[cfg(feature="perl")] #[cfg(feature="perl")]
internal: pcre2::bytes::Regex, internal: Arc<Mutex<pcre::Pcre>>,
#[cfg(not(feature = "perl"))] #[cfg(not(feature = "perl"))]
internal: regex::Regex, internal: regex::Regex,
} }
@ -50,18 +50,24 @@ impl Regex {
pub fn compile(string: impl AsRef<str>) -> Result<Self, Error> pub fn compile(string: impl AsRef<str>) -> Result<Self, Error>
{ {
#[cfg(feature = "perl")] #[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"))] #[cfg(not(feature = "perl"))]
return Ok(Self{internal: regex::Regex::new(string.as_ref())?}); 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")] #[cfg(feature = "perl")]
return { 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(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, None => None,
}) })
@ -70,7 +76,14 @@ impl Regex {
return { return {
Ok(match self.internal.captures(string.as_ref()) { Ok(match self.internal.captures(string.as_ref()) {
Some(m) => { 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, 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 impl From<regex::Error> for Error
{ {
fn from(er: regex::Error) -> Self fn from(er: regex::Error) -> Self
@ -96,9 +109,9 @@ impl From<regex::Error> for Error
} }
#[cfg(feature = "perl")] #[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)) Self::Compile(format!("{}", er))
} }

Loading…
Cancel
Save