diff --git a/src/re_bytes.rs b/src/re_bytes.rs index c8047229e8..8fdb133d43 100644 --- a/src/re_bytes.rs +++ b/src/re_bytes.rs @@ -1065,7 +1065,8 @@ impl<'c, 't> Iterator for SubCaptureMatches<'c, 't> { /// /// In general, users of this crate shouldn't need to implement this trait, /// since implementations are already provided for `&[u8]` and -/// `FnMut(&Captures) -> Vec`, which covers most use cases. +/// `FnMut(&Captures) -> Vec` (or any `FnMut(&Captures) -> T` +/// where `T: AsRef<[u8]>`), which covers most use cases. pub trait Replacer { /// Appends text to `dst` to replace the current match. /// @@ -1141,9 +1142,9 @@ impl<'a> Replacer for &'a [u8] { } } -impl Replacer for F where F: FnMut(&Captures) -> Vec { +impl Replacer for F where F: FnMut(&Captures) -> T, T: AsRef<[u8]> { fn replace_append(&mut self, caps: &Captures, dst: &mut Vec) { - dst.extend_from_slice(&(*self)(caps)); + dst.extend_from_slice((*self)(caps).as_ref()); } } diff --git a/src/re_unicode.rs b/src/re_unicode.rs index fd6e73aa4b..f71e7f5030 100644 --- a/src/re_unicode.rs +++ b/src/re_unicode.rs @@ -1107,7 +1107,8 @@ impl<'r, 't> Iterator for Matches<'r, 't> { /// /// In general, users of this crate shouldn't need to implement this trait, /// since implementations are already provided for `&str` and -/// `FnMut(&Captures) -> String`, which covers most use cases. +/// `FnMut(&Captures) -> String` (or any `FnMut(&Captures) -> T` +/// where `T: AsRef`), which covers most use cases. pub trait Replacer { /// Appends text to `dst` to replace the current match. /// @@ -1183,9 +1184,9 @@ impl<'a> Replacer for &'a str { } } -impl Replacer for F where F: FnMut(&Captures) -> String { +impl Replacer for F where F: FnMut(&Captures) -> T, T: AsRef { fn replace_append(&mut self, caps: &Captures, dst: &mut String) { - dst.push_str(&(*self)(caps)); + dst.push_str((*self)(caps).as_ref()); } } diff --git a/tests/macros_bytes.rs b/tests/macros_bytes.rs index d6e406bd1a..7605d69b21 100644 --- a/tests/macros_bytes.rs +++ b/tests/macros_bytes.rs @@ -2,6 +2,7 @@ macro_rules! text { ($text:expr) => { $text.as_bytes() } } macro_rules! t { ($re:expr) => { text!($re) } } macro_rules! match_text { ($text:expr) => { $text.as_bytes() } } +macro_rules! use_ { ($($path: tt)*) => { use regex::bytes::$($path)*; } } macro_rules! bytes { ($text:expr) => { $text } } diff --git a/tests/macros_str.rs b/tests/macros_str.rs index 8f490f1420..fda5814b8c 100644 --- a/tests/macros_str.rs +++ b/tests/macros_str.rs @@ -2,6 +2,7 @@ macro_rules! text { ($text:expr) => { $text } } macro_rules! t { ($text:expr) => { text!($text) } } macro_rules! match_text { ($text:expr) => { $text.as_str() } } +macro_rules! use_ { ($($path: tt)*) => { use regex::$($path)*; } } macro_rules! no_expand { ($text:expr) => {{ diff --git a/tests/replace.rs b/tests/replace.rs index 28b9df927e..6d5a5b13b0 100644 --- a/tests/replace.rs +++ b/tests/replace.rs @@ -33,6 +33,12 @@ replace!(no_expand1, replace, r"(\S+)\s+(\S+)", "w1 w2", no_expand!("$2 $1"), "$2 $1"); replace!(no_expand2, replace, r"(\S+)\s+(\S+)", "w1 w2", no_expand!("$$1"), "$$1"); +use_!(Captures); +replace!(closure_returning_reference, replace, r"(\d+)", "age: 26", + | captures: &Captures | &match_text!(captures.get(1).unwrap())[0..1], "age: 2"); +replace!(closure_returning_value, replace, r"\d+", "age: 26", + | _captures: &Captures | t!("Z").to_owned(), "age: Z"); + // See https://github.com/rust-lang/regex/issues/314 replace!(match_at_start_replace_with_empty, replace_all, r"foo", "foobar", t!(""), "bar");