/*!
The `search_stream` module is responsible for searching a single file and
printing matches. In particular, it searches the file in a streaming fashion
using `read` calls and a (roughly) fixed size buffer.
*/
use std::cmp;
use std::error::Error as StdError;
use std::fmt;
use std::io;
use std::path::{Path, PathBuf};
use bytecount;
use grep::{Grep, Match};
use memchr::{memchr, memrchr};
use termcolor::WriteColor;
use printer::Printer;
/// The default read size (capacity of input buffer).
const READ_SIZE: usize = 8 * (1<<10);
/// Error describes errors that can occur while searching.
#[derive(Debug)]
pub enum Error {
/// A standard I/O error attached to a particular file path.
Io {
err: io::Error,
path: PathBuf,
}
}
impl Error {
fn from_io<P: AsRef<Path>>(err: io::Error, path: P) -> Error {
Error::Io { err: err, path: path.as_ref().to_path_buf() }
}
}
impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::Io { ref err, .. } => err.description(),
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Error::Io { ref err, .. } => Some(err),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Io { ref err, ref path } => {
write!(f, "{}: {}", path.display(), err)
}
}
}
}
pub struct Searcher<'a, R, W: 'a> {
opts: Options,
inp