Skip to content

Commit 515382f

Browse files
committed
Loosen type-constraits, fix typos, add test
1 parent 76c92f9 commit 515382f

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

src/ffi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub trait CodeUnitWidth: std::fmt::Debug {
9090
type pcre2_match_context;
9191
type pcre2_match_data;
9292
type pcre2_jit_stack;
93-
type PCRE2_CHAR;
93+
type PCRE2_CHAR: TryInto<Self::SubjectChar>;
9494
type PCRE2_SPTR;
9595
type name_table_entry: NameTableEntry;
9696
type SubjectChar: Copy;

src/regex_impl.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ impl<W: CodeUnitWidth> Regex<W> {
496496
&self.capture_names_idx
497497
}
498498

499-
/// Replace the first instance of
499+
/// Replace the first match in the subject string with the replacement
500+
/// If `extended` is true, enable PCRE2's extended replacement syntax.
500501
pub fn replace<'s>(
501502
&self,
502503
subject: &'s [W::SubjectChar],
@@ -505,13 +506,12 @@ impl<W: CodeUnitWidth> Regex<W> {
505506
) -> Result<Cow<'s, [W::SubjectChar]>, Error>
506507
where
507508
[<W as CodeUnitWidth>::PCRE2_CHAR]: ToOwned,
508-
W::PCRE2_CHAR: TryInto<W::SubjectChar>,
509-
<<W as CodeUnitWidth>::PCRE2_CHAR as TryInto<<W as CodeUnitWidth>::SubjectChar>>::Error:
510-
std::fmt::Debug,
511509
{
512510
self.replace_impl(subject, replacement, false, extended)
513511
}
514512

513+
/// Replace all non-overlapping matches in the subject string with the replacement
514+
/// If `extended` is true, enable PCRE2's extended replacement syntax.
515515
pub fn replace_all<'s>(
516516
&self,
517517
subject: &'s [W::SubjectChar],
@@ -520,9 +520,6 @@ impl<W: CodeUnitWidth> Regex<W> {
520520
) -> Result<Cow<'s, [W::SubjectChar]>, Error>
521521
where
522522
[<W as CodeUnitWidth>::PCRE2_CHAR]: ToOwned,
523-
W::PCRE2_CHAR: TryInto<W::SubjectChar>,
524-
<<W as CodeUnitWidth>::PCRE2_CHAR as TryInto<<W as CodeUnitWidth>::SubjectChar>>::Error:
525-
std::fmt::Debug,
526523
{
527524
self.replace_impl(subject, replacement, true, extended)
528525
}
@@ -537,13 +534,10 @@ impl<W: CodeUnitWidth> Regex<W> {
537534
) -> Result<Cow<'s, [W::SubjectChar]>, Error>
538535
where
539536
[<W as CodeUnitWidth>::PCRE2_CHAR]: ToOwned,
540-
W::PCRE2_CHAR: TryInto<W::SubjectChar>,
541-
<<W as CodeUnitWidth>::PCRE2_CHAR as TryInto<<W as CodeUnitWidth>::SubjectChar>>::Error:
542-
std::fmt::Debug,
543537
{
544538
let mut options: u32 = 0;
545539
options |= PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
546-
// TODO: this should probably be configurabe from user-side
540+
// TODO: this should probably be configurable from user-side
547541
options |= PCRE2_SUBSTITUTE_UNSET_EMPTY;
548542
if extended {
549543
options |= PCRE2_SUBSTITUTE_EXTENDED;
@@ -585,16 +579,21 @@ impl<W: CodeUnitWidth> Regex<W> {
585579
0 => Cow::Borrowed(subject),
586580
_ => {
587581
// +1 to account for null terminator
588-
unsafe { output.set_len(capacity + 1) };
582+
unsafe { output.set_len(capacity + 1) };
583+
584+
// All inputs contained valid chars, so we expect all outputs to as well.
585+
let to_char = |c: W::PCRE2_CHAR| -> W::SubjectChar {
586+
c.try_into()
587+
.unwrap_or_else(|_| panic!("all output expected to be valid chars"))
588+
};
589589

590590
// this is really just a type cast
591591
let x: Vec<W::SubjectChar> = output
592592
.into_iter()
593-
.map(W::PCRE2_CHAR::try_into)
593+
.map(to_char)
594594
// we don't want to return the null terminator
595595
.take(capacity)
596-
.collect::<Result<Vec<W::SubjectChar>, _>>()
597-
.expect("PCRE2 returned invalid characters");
596+
.collect::<Vec<W::SubjectChar>>();
598597

599598
Cow::Owned(x)
600599
}

src/utf32.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub type Captures<'s> = CapturesImpl<'s, CodeUnitWidth32>;
3333

3434
#[cfg(test)]
3535
mod tests {
36+
use std::borrow::Cow;
37+
3638
use super::{CodeUnitWidth32, Regex, RegexBuilder};
3739
use crate::is_jit_available;
3840

@@ -114,6 +116,20 @@ mod tests {
114116
assert!(re.is_match(&b("foo\nabc\nbar")).unwrap());
115117
}
116118

119+
#[test]
120+
fn replace() {
121+
let re = RegexBuilder::new().build(b(".")).unwrap();
122+
let s = b("abc");
123+
let r = b("");
124+
let replaced = re.replace(&s, &r, true).unwrap();
125+
assert!(
126+
matches!(replaced, Cow::Owned(_)),
127+
"a replacement should give a new string"
128+
);
129+
let replaced = replaced.into_owned();
130+
assert_eq!(replaced, &*b("bc"));
131+
}
132+
117133
#[test]
118134
fn ucp() {
119135
let re = RegexBuilder::new().ucp(false).build(b(r"\w")).unwrap();

0 commit comments

Comments
 (0)