ripgrep-all/src/adapters/writing.rs

66 lines
1.8 KiB
Rust
Raw Normal View History

2020-06-11 21:09:31 +00:00
use super::{FileAdapter, GetMetadata, ReadBox};
use anyhow::Result;
2020-09-28 20:55:55 +00:00
use std::io::Read;
2020-06-11 21:09:31 +00:00
use std::io::Write;
2020-09-28 20:55:55 +00:00
use std::thread::Thread;
2020-06-11 21:09:31 +00:00
2020-09-10 15:18:11 +00:00
// this trait / struct split is ugly but necessary because of "conflicting trait implementation" otherwise with SpawningFileAdapter
2020-06-11 21:09:31 +00:00
#[dyn_clonable::clonable]
pub trait WritingFileAdapterTrait: GetMetadata + Send + Clone {
2020-09-10 15:18:11 +00:00
fn adapt_write<'a>(
2020-06-11 21:09:31 +00:00
&self,
2020-09-10 15:18:11 +00:00
a: super::AdaptInfo<'a>,
2020-06-17 09:45:06 +00:00
detection_reason: &crate::matching::FileMatcher,
2020-09-10 15:18:11 +00:00
oup: &mut (dyn Write + 'a),
2020-06-11 21:09:31 +00:00
) -> Result<()>;
}
pub struct WritingFileAdapter {
inner: Box<dyn WritingFileAdapterTrait>,
}
impl WritingFileAdapter {
pub fn new(inner: Box<dyn WritingFileAdapterTrait>) -> WritingFileAdapter {
WritingFileAdapter { inner }
}
}
impl GetMetadata for WritingFileAdapter {
fn metadata(&self) -> &super::AdapterMeta {
self.inner.metadata()
}
}
2020-09-28 20:55:55 +00:00
struct PipedReadWriter<'a> {
inner: ReadBox<'a>,
pipe_thread: Thread,
}
impl<'a> Read for PipedReadWriter<'a> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
todo!()
}
}
2020-06-11 21:09:31 +00:00
impl FileAdapter for WritingFileAdapter {
2020-09-10 15:18:11 +00:00
fn adapt<'a>(
2020-06-11 21:09:31 +00:00
&self,
2020-09-10 15:18:11 +00:00
ai_outer: super::AdaptInfo<'a>,
2020-06-17 09:45:06 +00:00
detection_reason: &crate::matching::FileMatcher,
2020-09-10 15:18:11 +00:00
) -> anyhow::Result<ReadBox<'a>> {
2020-06-11 21:09:31 +00:00
let (r, w) = crate::pipe::pipe();
let cc = self.inner.clone();
let detc = detection_reason.clone();
std::thread::spawn(move || {
let mut oup = w;
2020-09-10 15:18:11 +00:00
let ai = ai_outer;
2020-06-11 21:09:31 +00:00
let res = cc.adapt_write(ai, &detc, &mut oup);
if let Err(e) = res {
oup.write_err(std::io::Error::new(std::io::ErrorKind::Other, e))
.expect("could not write err");
}
});
Ok(Box::new(r))
}
}