2020-06-11 21:09:31 +00:00
|
|
|
use super::{FileAdapter, GetMetadata, ReadBox};
|
|
|
|
use anyhow::Result;
|
|
|
|
use std::io::Write;
|
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|