From 9925d55dfd91dce8eef881884c5828b052bde895 Mon Sep 17 00:00:00 2001 From: nooberfsh Date: Wed, 2 Dec 2020 14:51:45 +0800 Subject: [PATCH 1/3] implement `regex::Replacer` for `String`, `&String`, `Cow<'a, str>`, `&Cow<'a, str'>` --- src/re_unicode.rs | 53 +++++++++++++++++++++++++++++++++++++++++++---- tests/replace.rs | 49 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src/re_unicode.rs b/src/re_unicode.rs index ea95c1b6df..bb2475312e 100644 --- a/src/re_unicode.rs +++ b/src/re_unicode.rs @@ -1190,10 +1190,55 @@ impl<'a> Replacer for &'a str { } fn no_expansion(&mut self) -> Option> { - match find_byte(b'$', self.as_bytes()) { - Some(_) => None, - None => Some(Cow::Borrowed(*self)), - } + no_expansion(self) + } +} + +impl<'a> Replacer for &'a String { + fn replace_append(&mut self, caps: &Captures, dst: &mut String) { + self.as_str().replace_append(caps, dst) + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl Replacer for String { + fn replace_append(&mut self, caps: &Captures, dst: &mut String) { + self.as_str().replace_append(caps, dst) + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl<'a> Replacer for Cow<'a, str> { + fn replace_append(&mut self, caps: &Captures, dst: &mut String) { + self.as_ref().replace_append(caps, dst) + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl<'a> Replacer for &'a Cow<'a, str> { + fn replace_append(&mut self, caps: &Captures, dst: &mut String) { + self.as_ref().replace_append(caps, dst) + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +fn no_expansion>(t: &T) -> Option> { + let s = t.as_ref(); + match find_byte(b'$', s.as_bytes()) { + Some(_) => None, + None => Some(Cow::Borrowed(s)), } } diff --git a/tests/replace.rs b/tests/replace.rs index c156a399ff..9d155147a2 100644 --- a/tests/replace.rs +++ b/tests/replace.rs @@ -130,3 +130,52 @@ replace!( t!("${1}a $1a"), "ba " ); + +replace!( + impl_string, + replace, + r"[0-9]", + "age: 26", + t!("Z".to_string()), + "age: Z6" +); +replace!( + impl_string_ref, + replace, + r"[0-9]", + "age: 26", + t!(&"Z".to_string()), + "age: Z6" +); +replace!( + impl_cow_borrowed, + replace, + r"[0-9]", + "age: 26", + t!(std::borrow::Cow::<'_, str>::Borrowed("Z")), + "age: Z6" +); +replace!( + impl_cow_borrowed_ref, + replace, + r"[0-9]", + "age: 26", + t!(&std::borrow::Cow::<'_, str>::Borrowed("Z")), + "age: Z6" +); +replace!( + impl_cow_owned, + replace, + r"[0-9]", + "age: 26", + t!(std::borrow::Cow::<'_, str>::Owned("Z".to_string())), + "age: Z6" +); +replace!( + impl_cow_owned_ref, + replace, + r"[0-9]", + "age: 26", + t!(&std::borrow::Cow::<'_, str>::Owned("Z".to_string())), + "age: Z6" +); From 55bc01a044e28d8f079a3fd65d1df53d4ecdd4d5 Mon Sep 17 00:00:00 2001 From: nooberfsh Date: Fri, 4 Dec 2020 15:09:38 +0800 Subject: [PATCH 2/3] implement `regex::Replacer` for `Vec`, `&Vec`, `Cow<'a, [u8]>`, `&Cow<'a, [u8]>` --- src/re_bytes.rs | 53 +++++++++++++++++++++++++++++++++++++--- tests/macros_bytes.rs | 1 - tests/macros_str.rs | 1 + tests/replace.rs | 57 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/re_bytes.rs b/src/re_bytes.rs index ca01e0ec98..481ff51fa4 100644 --- a/src/re_bytes.rs +++ b/src/re_bytes.rs @@ -1148,10 +1148,55 @@ impl<'a> Replacer for &'a [u8] { } fn no_expansion(&mut self) -> Option> { - match find_byte(b'$', *self) { - Some(_) => None, - None => Some(Cow::Borrowed(*self)), - } + no_expansion(self) + } +} + +impl<'a> Replacer for &'a Vec { + fn replace_append(&mut self, caps: &Captures, dst: &mut Vec) { + caps.expand(*self, dst); + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl Replacer for Vec { + fn replace_append(&mut self, caps: &Captures, dst: &mut Vec) { + caps.expand(self, dst); + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl<'a> Replacer for Cow<'a, [u8]> { + fn replace_append(&mut self, caps: &Captures, dst: &mut Vec) { + caps.expand(self.as_ref(), dst); + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +impl<'a> Replacer for &'a Cow<'a, [u8]> { + fn replace_append(&mut self, caps: &Captures, dst: &mut Vec) { + caps.expand(self.as_ref(), dst); + } + + fn no_expansion(&mut self) -> Option> { + no_expansion(self) + } +} + +fn no_expansion>(t: &T) -> Option> { + let s = t.as_ref(); + match find_byte(b'$', s) { + Some(_) => None, + None => Some(Cow::Borrowed(s)), } } diff --git a/tests/macros_bytes.rs b/tests/macros_bytes.rs index 03c370d698..3d6c8c3ac8 100644 --- a/tests/macros_bytes.rs +++ b/tests/macros_bytes.rs @@ -4,7 +4,6 @@ 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! empty_vec { () => { >::new() } } - macro_rules! bytes { ($text:expr) => { $text } } macro_rules! no_expand { diff --git a/tests/macros_str.rs b/tests/macros_str.rs index 9b996b33b9..7b7eb110c2 100644 --- a/tests/macros_str.rs +++ b/tests/macros_str.rs @@ -4,6 +4,7 @@ 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! empty_vec { () => { >::new() } } +macro_rules! bytes { ($text:expr) => { std::str::from_utf8($text.as_ref()).unwrap() } } macro_rules! no_expand { ($text:expr) => {{ diff --git a/tests/replace.rs b/tests/replace.rs index 9d155147a2..700aff2430 100644 --- a/tests/replace.rs +++ b/tests/replace.rs @@ -148,7 +148,7 @@ replace!( "age: Z6" ); replace!( - impl_cow_borrowed, + impl_cow_str_borrowed, replace, r"[0-9]", "age: 26", @@ -156,7 +156,7 @@ replace!( "age: Z6" ); replace!( - impl_cow_borrowed_ref, + impl_cow_str_borrowed_ref, replace, r"[0-9]", "age: 26", @@ -164,7 +164,7 @@ replace!( "age: Z6" ); replace!( - impl_cow_owned, + impl_cow_str_owned, replace, r"[0-9]", "age: 26", @@ -172,10 +172,59 @@ replace!( "age: Z6" ); replace!( - impl_cow_owned_ref, + impl_cow_str_owned_ref, replace, r"[0-9]", "age: 26", t!(&std::borrow::Cow::<'_, str>::Owned("Z".to_string())), "age: Z6" ); + +replace!( + impl_vec_u8, + replace, + r"[0-9]", + "age: 26", + bytes!(vec![b'Z']), + "age: Z6" +); +replace!( + impl_vec_u8_ref, + replace, + r"[0-9]", + "age: 26", + bytes!(&vec![b'Z']), + "age: Z6" +); +replace!( + impl_cow_slice_borrowed, + replace, + r"[0-9]", + "age: 26", + bytes!(std::borrow::Cow::<'_, [u8]>::Borrowed(&[b'Z'])), + "age: Z6" +); +replace!( + impl_cow_slice_borrowed_ref, + replace, + r"[0-9]", + "age: 26", + bytes!(&std::borrow::Cow::<'_, [u8]>::Borrowed(&[b'Z'])), + "age: Z6" +); +replace!( + impl_cow_slice_owned, + replace, + r"[0-9]", + "age: 26", + bytes!(std::borrow::Cow::<'_, [u8]>::Owned(vec![b'Z'])), + "age: Z6" +); +replace!( + impl_cow_slice_owned_ref, + replace, + r"[0-9]", + "age: 26", + bytes!(&std::borrow::Cow::<'_, [u8]>::Owned(vec![b'Z'])), + "age: Z6" +); From efe2dd2c91bd184f85810a68aa185b161390e620 Mon Sep 17 00:00:00 2001 From: nooberfsh Date: Fri, 4 Dec 2020 15:29:07 +0800 Subject: [PATCH 3/3] update docs for `Replacer` --- src/re_bytes.rs | 6 +++--- src/re_unicode.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/re_bytes.rs b/src/re_bytes.rs index 481ff51fa4..5ef41bc1b4 100644 --- a/src/re_bytes.rs +++ b/src/re_bytes.rs @@ -1077,9 +1077,9 @@ impl<'c, 't> Iterator for SubCaptureMatches<'c, 't> { /// string. /// /// In general, users of this crate shouldn't need to implement this trait, -/// since implementations are already provided for `&[u8]` and -/// `FnMut(&Captures) -> Vec` (or any `FnMut(&Captures) -> T` -/// where `T: AsRef<[u8]>`), which covers most use cases. +/// since implementations are already provided for `&[u8]` along with other +/// variants of bytes types and `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. /// diff --git a/src/re_unicode.rs b/src/re_unicode.rs index bb2475312e..afdc61d218 100644 --- a/src/re_unicode.rs +++ b/src/re_unicode.rs @@ -1119,9 +1119,9 @@ impl<'r, 't> Iterator for Matches<'r, 't> { /// Replacer describes types that can be used to replace matches in a string. /// /// In general, users of this crate shouldn't need to implement this trait, -/// since implementations are already provided for `&str` and -/// `FnMut(&Captures) -> String` (or any `FnMut(&Captures) -> T` -/// where `T: AsRef`), which covers most use cases. +/// since implementations are already provided for `&str` along with other +/// variants of string types and `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. ///