summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/app.rs10
-rw-r--r--src/input.rs90
-rw-r--r--src/main.rs2
3 files changed, 49 insertions, 53 deletions
diff --git a/src/app.rs b/src/app.rs
index 28de460..f170540 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,4 +1,4 @@
-use crate::{Error, Source, Stream};
+use crate::{Error, Replacer, Source};
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
@@ -35,9 +35,7 @@ pub(crate) struct Options {
pub(crate) fn run() -> Result<(), Error> {
let args = Options::from_args();
let source = Source::from(args.file_path);
- let mut stream: Stream = (&source).into_stream()?;
- stream.replace(!args.literal_mode, &args.find, &args.replace_with)?;
-
- // replace file in-place, or pipe to stdout
- stream.output(&source, args.in_place)
+ let replacer = Replacer::new(&args.find, &args.replace_with, args.literal_mode)?;
+ replacer.replace(&source, args.in_place)?;
+ Ok(())
}
diff --git a/src/input.rs b/src/input.rs
index 7df9f77..19c7391 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,8 +1,49 @@
use {
crate::{utils, Error},
+ regex::Regex,
std::{fs::File, io::prelude::*},
};
+pub(crate) enum Replacer<'a> {
+ Regex(Regex, &'a str),
+ Literal(&'a str, &'a str),
+}
+
+impl<'a> Replacer<'a> {
+ pub(crate) fn new(look_for: &'a str, replace_with: &'a str, is_literal: bool) -> Result<Self, Error> {
+ if is_literal {
+ return Ok(Replacer::Literal(look_for, replace_with));
+ }
+ return Ok(Replacer::Regex(regex::Regex::new(look_for)?, replace_with));
+ }
+
+ pub(crate) fn replace(&self, source: &Source, in_place: bool) -> Result<(), Error> {
+ let content = source.to_string()?;
+ let replaced = match self {
+ Replacer::Regex(regex, replace_with) => {
+ let replaced = regex.replace_all(&content, *replace_with).to_string();
+ utils::unescape(&replaced).unwrap_or_else(|| replaced)
+ }
+ Replacer::Literal(search, replace_with) => content.replace(search, replace_with),
+ };
+
+ Replacer::output(source, replaced, in_place)
+ }
+
+ fn output(source: &Source, data: String, in_place: bool) -> Result<(), Error> {
+ use atomic_write::atomic_write;
+ match (source, in_place) {
+ (Source::Stdin, _) | (Source::File(_), false) => {
+ let stdout = std::io::stdout();
+ let mut handle = stdout.lock();
+ handle.write(data.as_bytes())?;
+ Ok(())
+ }
+ (Source::File(path), true) => Ok(atomic_write(path, data)?),
+ }
+ }
+}
+
pub(crate) enum Source {
Stdin,
File(String),
@@ -15,65 +56,22 @@ impl Source {
.unwrap_or_else(|| Source::Stdin)
}
- pub(crate) fn into_stream(&self) -> Result<Stream, Error> {
+ pub(crate) fn to_string(&self) -> Result<String, Error> {
match self {
Source::Stdin => {
let mut buffer = String::new();
let stdin = std::io::stdin();
let mut handle = stdin.lock();
handle.read_to_string(&mut buffer)?;
- Ok(Stream::new(buffer))
+ Ok(buffer)
}
Source::File(path) => {
let file = File::open(path)?;
let mut buf_reader = std::io::BufReader::new(file);
let mut buffer = String::new();
buf_reader.read_to_string(&mut buffer)?;
- Ok(Stream::new(buffer))
- }
- }
- }
-}
-
-pub(crate) struct Stream {
- data: String,
-}
-
-impl Stream {
- pub(crate) fn new(data: String) -> Self {
- Self { data }
- }
-
- pub(crate) fn replace(
- &mut self,
- is_regex: bool,
- look_for: &str,
- replace_with: &str,
- ) -> Result<(), crate::Error> {
- if is_regex {
- let replaced = regex::Regex::new(look_for)?
- .replace_all(&self.data, replace_with)
- .to_string();
- self.data = utils::unescape(&replaced).unwrap_or_else(|| replaced);
- } else {
- self.data = self.data.replace(look_for, replace_with);
- }
- Ok(())
- }
-
- // Output based on input.
- // When dealing with a file, transform it in-place.
- // Otherwise, pipe to stdout.
- pub(crate) fn output(self, source: &Source, in_place: bool) -> Result<(), crate::Error> {
- use atomic_write::atomic_write;
- match (source, in_place) {
- (Source::Stdin, _) | (Source::File(_), false) => {
- let stdout = std::io::stdout();
- let mut handle = stdout.lock();
- handle.write(self.data.as_bytes())?;
- Ok(())
+ Ok(buffer)
}
- (Source::File(path), true) => Ok(atomic_write(path, self.data)?),
}
}
}
diff --git a/src/main.rs b/src/main.rs
index feb315c..eb0b12f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,7 +5,7 @@ pub(crate) mod utils;
pub(crate) use {
crate::error::Error,
- crate::input::{Source, Stream},
+ crate::input::{Replacer, Source},
};
fn main() -> Result<(), Error> {