/*!
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.
*/
extern crate bytecount;
use std::cmp;
use std::error::Error as StdError;
use std::fmt;
use std::io;
use std::path::{Path, PathBuf};
use grep::{Grep, Match};
use memchr::{memchr, memrchr};
use term::Terminal;
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: &'a mut InputBuffer,
printer: &'a mut Printer<W>,
grep: &'a Grep,
path: &'a Path,
haystack: R,
match_count: u64,
line_count: Option<u64>,
last_match: Match,
last_printed: usize,
last_line: usize,
after_context_remaining: usize,
}
/// Options for configuring search.
#[derive(Clone)]
pub struct Options {
pub after_context: usize,
pub