Skip to content

Commit 2bab987

Browse files
authored
api: Replacer for more string types
And do the same for the bytes oriented APIs. This results in some small quality of life improvements when using the Replacer trait with a string type that isn't &str. PR #728
1 parent 373d5ca commit 2bab987

File tree

5 files changed

+203
-15
lines changed

5 files changed

+203
-15
lines changed

src/re_bytes.rs

+52-7
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,9 @@ impl<'c, 't> FusedIterator for SubCaptureMatches<'c, 't> {}
11051105
/// string.
11061106
///
11071107
/// In general, users of this crate shouldn't need to implement this trait,
1108-
/// since implementations are already provided for `&[u8]` and
1109-
/// `FnMut(&Captures) -> Vec<u8>` (or any `FnMut(&Captures) -> T`
1110-
/// where `T: AsRef<[u8]>`), which covers most use cases.
1108+
/// since implementations are already provided for `&[u8]` along with other
1109+
/// variants of bytes types and `FnMut(&Captures) -> Vec<u8>` (or any
1110+
/// `FnMut(&Captures) -> T` where `T: AsRef<[u8]>`), which covers most use cases.
11111111
pub trait Replacer {
11121112
/// Appends text to `dst` to replace the current match.
11131113
///
@@ -1176,10 +1176,55 @@ impl<'a> Replacer for &'a [u8] {
11761176
}
11771177

11781178
fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
1179-
match find_byte(b'$', *self) {
1180-
Some(_) => None,
1181-
None => Some(Cow::Borrowed(*self)),
1182-
}
1179+
no_expansion(self)
1180+
}
1181+
}
1182+
1183+
impl<'a> Replacer for &'a Vec<u8> {
1184+
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
1185+
caps.expand(*self, dst);
1186+
}
1187+
1188+
fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
1189+
no_expansion(self)
1190+
}
1191+
}
1192+
1193+
impl Replacer for Vec<u8> {
1194+
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
1195+
caps.expand(self, dst);
1196+
}
1197+
1198+
fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
1199+
no_expansion(self)
1200+
}
1201+
}
1202+
1203+
impl<'a> Replacer for Cow<'a, [u8]> {
1204+
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
1205+
caps.expand(self.as_ref(), dst);
1206+
}
1207+
1208+
fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
1209+
no_expansion(self)
1210+
}
1211+
}
1212+
1213+
impl<'a> Replacer for &'a Cow<'a, [u8]> {
1214+
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
1215+
caps.expand(self.as_ref(), dst);
1216+
}
1217+
1218+
fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
1219+
no_expansion(self)
1220+
}
1221+
}
1222+
1223+
fn no_expansion<T: AsRef<[u8]>>(t: &T) -> Option<Cow<[u8]>> {
1224+
let s = t.as_ref();
1225+
match find_byte(b'$', s) {
1226+
Some(_) => None,
1227+
None => Some(Cow::Borrowed(s)),
11831228
}
11841229
}
11851230

src/re_unicode.rs

+52-7
Original file line numberDiff line numberDiff line change
@@ -1147,9 +1147,9 @@ impl<'r, 't> FusedIterator for Matches<'r, 't> {}
11471147
/// Replacer describes types that can be used to replace matches in a string.
11481148
///
11491149
/// In general, users of this crate shouldn't need to implement this trait,
1150-
/// since implementations are already provided for `&str` and
1151-
/// `FnMut(&Captures) -> String` (or any `FnMut(&Captures) -> T`
1152-
/// where `T: AsRef<str>`), which covers most use cases.
1150+
/// since implementations are already provided for `&str` along with other
1151+
/// variants of string types and `FnMut(&Captures) -> String` (or any
1152+
/// `FnMut(&Captures) -> T` where `T: AsRef<str>`), which covers most use cases.
11531153
pub trait Replacer {
11541154
/// Appends text to `dst` to replace the current match.
11551155
///
@@ -1218,10 +1218,55 @@ impl<'a> Replacer for &'a str {
12181218
}
12191219

12201220
fn no_expansion(&mut self) -> Option<Cow<str>> {
1221-
match find_byte(b'$', self.as_bytes()) {
1222-
Some(_) => None,
1223-
None => Some(Cow::Borrowed(*self)),
1224-
}
1221+
no_expansion(self)
1222+
}
1223+
}
1224+
1225+
impl<'a> Replacer for &'a String {
1226+
fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
1227+
self.as_str().replace_append(caps, dst)
1228+
}
1229+
1230+
fn no_expansion(&mut self) -> Option<Cow<str>> {
1231+
no_expansion(self)
1232+
}
1233+
}
1234+
1235+
impl Replacer for String {
1236+
fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
1237+
self.as_str().replace_append(caps, dst)
1238+
}
1239+
1240+
fn no_expansion(&mut self) -> Option<Cow<str>> {
1241+
no_expansion(self)
1242+
}
1243+
}
1244+
1245+
impl<'a> Replacer for Cow<'a, str> {
1246+
fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
1247+
self.as_ref().replace_append(caps, dst)
1248+
}
1249+
1250+
fn no_expansion(&mut self) -> Option<Cow<str>> {
1251+
no_expansion(self)
1252+
}
1253+
}
1254+
1255+
impl<'a> Replacer for &'a Cow<'a, str> {
1256+
fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
1257+
self.as_ref().replace_append(caps, dst)
1258+
}
1259+
1260+
fn no_expansion(&mut self) -> Option<Cow<str>> {
1261+
no_expansion(self)
1262+
}
1263+
}
1264+
1265+
fn no_expansion<T: AsRef<str>>(t: &T) -> Option<Cow<str>> {
1266+
let s = t.as_ref();
1267+
match find_byte(b'$', s.as_bytes()) {
1268+
Some(_) => None,
1269+
None => Some(Cow::Borrowed(s)),
12251270
}
12261271
}
12271272

tests/macros_bytes.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ macro_rules! t { ($re:expr) => { text!($re) } }
44
macro_rules! match_text { ($text:expr) => { $text.as_bytes() } }
55
macro_rules! use_ { ($($path: tt)*) => { use regex::bytes::$($path)*; } }
66
macro_rules! empty_vec { () => { <Vec<&[u8]>>::new() } }
7-
87
macro_rules! bytes { ($text:expr) => { $text } }
98

109
macro_rules! no_expand {

tests/macros_str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ macro_rules! t { ($text:expr) => { text!($text) } }
44
macro_rules! match_text { ($text:expr) => { $text.as_str() } }
55
macro_rules! use_ { ($($path: tt)*) => { use regex::$($path)*; } }
66
macro_rules! empty_vec { () => { <Vec<&str>>::new() } }
7+
macro_rules! bytes { ($text:expr) => { std::str::from_utf8($text.as_ref()).unwrap() } }
78

89
macro_rules! no_expand {
910
($text:expr) => {{

tests/replace.rs

+98
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,101 @@ replace!(
130130
t!("${1}a $1a"),
131131
"ba "
132132
);
133+
134+
replace!(
135+
impl_string,
136+
replace,
137+
r"[0-9]",
138+
"age: 26",
139+
t!("Z".to_string()),
140+
"age: Z6"
141+
);
142+
replace!(
143+
impl_string_ref,
144+
replace,
145+
r"[0-9]",
146+
"age: 26",
147+
t!(&"Z".to_string()),
148+
"age: Z6"
149+
);
150+
replace!(
151+
impl_cow_str_borrowed,
152+
replace,
153+
r"[0-9]",
154+
"age: 26",
155+
t!(std::borrow::Cow::<'_, str>::Borrowed("Z")),
156+
"age: Z6"
157+
);
158+
replace!(
159+
impl_cow_str_borrowed_ref,
160+
replace,
161+
r"[0-9]",
162+
"age: 26",
163+
t!(&std::borrow::Cow::<'_, str>::Borrowed("Z")),
164+
"age: Z6"
165+
);
166+
replace!(
167+
impl_cow_str_owned,
168+
replace,
169+
r"[0-9]",
170+
"age: 26",
171+
t!(std::borrow::Cow::<'_, str>::Owned("Z".to_string())),
172+
"age: Z6"
173+
);
174+
replace!(
175+
impl_cow_str_owned_ref,
176+
replace,
177+
r"[0-9]",
178+
"age: 26",
179+
t!(&std::borrow::Cow::<'_, str>::Owned("Z".to_string())),
180+
"age: Z6"
181+
);
182+
183+
replace!(
184+
impl_vec_u8,
185+
replace,
186+
r"[0-9]",
187+
"age: 26",
188+
bytes!(vec![b'Z']),
189+
"age: Z6"
190+
);
191+
replace!(
192+
impl_vec_u8_ref,
193+
replace,
194+
r"[0-9]",
195+
"age: 26",
196+
bytes!(&vec![b'Z']),
197+
"age: Z6"
198+
);
199+
replace!(
200+
impl_cow_slice_borrowed,
201+
replace,
202+
r"[0-9]",
203+
"age: 26",
204+
bytes!(std::borrow::Cow::<'_, [u8]>::Borrowed(&[b'Z'])),
205+
"age: Z6"
206+
);
207+
replace!(
208+
impl_cow_slice_borrowed_ref,
209+
replace,
210+
r"[0-9]",
211+
"age: 26",
212+
bytes!(&std::borrow::Cow::<'_, [u8]>::Borrowed(&[b'Z'])),
213+
"age: Z6"
214+
);
215+
replace!(
216+
impl_cow_slice_owned,
217+
replace,
218+
r"[0-9]",
219+
"age: 26",
220+
bytes!(std::borrow::Cow::<'_, [u8]>::Owned(vec![b'Z'])),
221+
"age: Z6"
222+
);
223+
replace!(
224+
impl_cow_slice_owned_ref,
225+
replace,
226+
r"[0-9]",
227+
"age: 26",
228+
bytes!(&std::borrow::Cow::<'_, [u8]>::Owned(vec![b'Z'])),
229+
"age: Z6"
230+
);

0 commit comments

Comments
 (0)