use std::io;
use crate::searcher::Searcher;
pub trait SinkError: Sized {
fn error_message<T: std::fmt::Display>(message: T) -> Self;
fn error_io(err: io::Error) -> Self {
Self::error_message(err)
}
}
impl SinkError for io::Error {
fn error_message<T: std::fmt::Display>(message: T) -> io::Error {
io::Error::other(message.to_string())
}
fn error_io(err: io::Error) -> io::Error {
err
}
}
pub trait Sink {
type Error: SinkError;
fn matched(&mut self, _searcher: &Searcher, _mat: &SinkMatch<'_>) -> Result<bool, Self::Error>;
#[inline]
fn begin(&mut self, _searcher: &Searcher) -> Result<bool, Self::Error> {
Ok(true)
}
#[inline]
fn finish(&mut self, _searcher: &Searcher, _: &SinkFinish) -> Result<(), Self::Error> {
Ok(())
}
}
impl<S: Sink> Sink for &mut S {
type Error = S::Error;
#[inline]
fn matched(&mut self, searcher: &Searcher, mat: &SinkMatch<'_>) -> Result<bool, S::Error> {
(**self).matched(searcher, mat)
}
#[inline]
fn begin(&mut self, searcher: &Searcher) -> Result<bool, S::Error> {
(**self).begin(searcher)
}
#[inline]
fn finish(&mut self, searcher: &Searcher, sink_finish: &SinkFinish) -> Result<(), S::Error> {
(**self).finish(searcher, sink_finish)
}
}
#[derive(Clone, Debug)]
pub struct SinkFinish {
pub(crate) byte_count: u64,
}
impl SinkFinish {
#[inline]
pub fn byte_count(&self) -> u64 {
self.byte_count
}
}
#[derive(Clone, Debug)]
pub struct SinkMatch<'b> {
pub(crate) bytes: &'b [u8],
pub(crate) absolute_byte_offset: u64,
pub(crate) line_number: Option<u64>,
pub(crate) buffer: &'b [u8],
pub(crate) bytes_range_in_buffer: std::ops::Range<usize>,
}
impl<'b> SinkMatch<'b> {
#[inline]
pub fn bytes(&self) -> &'b [u8] {
self.bytes
}
#[inline]
pub fn absolute_byte_offset(&self) -> u64 {
self.absolute_byte_offset
}
#[inline]
pub fn line_number(&self) -> Option<u64> {
self.line_number
}
#[inline]
pub fn buffer(&self) -> &'b [u8] {
self.buffer
}
#[inline]
pub fn bytes_range_in_buffer(&self) -> std::ops::Range<usize> {
self.bytes_range_in_buffer.clone()
}
}