---
src/sed/edit.rs | 47 ++++++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/src/sed/edit.rs b/src/sed/edit.rs
index c80cde1..3d11d93 100644
--- a/src/sed/edit.rs
+++ b/src/sed/edit.rs
@@ -20,9 +20,13 @@ use super::parser::parse_substitute;
use super::types::{Address, Command, Substitute};
use itertools::Itertools;
+use std::borrow::Cow;
use std::iter::{empty, once, repeat};
-fn regex_replace<'a, I>(lines: I, arg: &str) -> Result<String, String>
+fn regex_replace<'a, I>(
+ lines: I,
+ arg: &'a str,
+) -> Result<impl Iterator<Item = Cow<'a, str>>, String>
where
I: Iterator<Item = &'a str>,
{
@@ -31,18 +35,14 @@ where
replacement,
flags,
} = parse_substitute(arg)?;
- let global = flags.contains('g');
- let rep: &str = replacement.as_ref();
- let replaced = lines.map(|line| {
- if global {
- pattern.replace_all(line, rep)
+ Ok(lines.map(move |line| {
+ if flags.contains('g') {
+ pattern.replace_all(line, &replacement[..])
} else {
- pattern.replace(line, rep)
+ pattern.replace(line, &replacement[..])
}
- });
-
- Ok(replaced.collect::<Vec<_>>().join("\n"))
+ }))
}
pub fn edit(text: &str, cmd: Command) -> Result<String, String> {
@@ -58,24 +58,29 @@ pub fn edit(text: &str, cmd: Command) -> Result<String, String> {
let editing_range = text.split('\n').skip(start).take(count);
let repeating_arg = repeat(arg.as_ref()).take(count);
- let tmp;
- let edited: Box<dyn Iterator<Item = &str>> = match command {
- 'a' => Box::new(editing_range.interleave_shortest(repeating_arg)),
- 'c' => Box::new(once(arg.as_ref())),
+ let edited: Box<dyn Iterator<Item = Cow<'_, str>>> = match command {
+ 'a' => Box::new(
+ editing_range
+ .interleave_shortest(repeating_arg)
+ .map(Cow::Borrowed),
+ ),
+ 'c' => Box::new(once(arg.as_ref()).map(Cow::Borrowed)),
'd' => Box::new(empty()),
- 'i' => Box::new(repeating_arg.interleave_shortest(editing_range)),
- 's' => {
- tmp = regex_replace(editing_range, &arg)?;
- Box::new(once(tmp.as_ref()))
- }
+ 'i' => Box::new(
+ repeating_arg
+ .interleave_shortest(editing_range)
+ .map(Cow::Borrowed),
+ ),
+ 's' => Box::new(regex_replace(editing_range, &arg)?),
_ => return Err(format!("Sed command `{}` not implemented!", command)),
};
Ok(text
.split('\n')
.take(start)
+ .map(Cow::Borrowed)
.chain(edited)
- .chain(text.split('\n').skip(start + count))
- .intersperse("\n")
+ .chain(text.split('\n').skip(start + count).map(Cow::Borrowed))
+ .intersperse(Cow::Borrowed("\n"))
.collect())
}
--
2.27.0