You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.2 KiB
Rust
76 lines
2.2 KiB
Rust
use std::pin::Pin;
|
|
|
|
use crate::{adapted_iter::one_file, join_handle_to_stream, to_io_err};
|
|
|
|
use super::{AdaptInfo, FileAdapter, GetMetadata};
|
|
use anyhow::Result;
|
|
use async_trait::async_trait;
|
|
use tokio::io::{AsyncReadExt, AsyncWrite};
|
|
|
|
#[async_trait]
|
|
pub trait WritingFileAdapter: GetMetadata + Send + Sync + Clone {
|
|
async fn adapt_write(
|
|
a: super::AdaptInfo,
|
|
detection_reason: &crate::matching::FileMatcher,
|
|
oup: Pin<Box<dyn AsyncWrite + Send>>,
|
|
) -> Result<()>;
|
|
}
|
|
|
|
macro_rules! async_writeln {
|
|
($dst: expr) => {
|
|
{
|
|
tokio::io::AsyncWriteExt::write_all(&mut $dst, b"\n").await
|
|
}
|
|
};
|
|
($dst: expr, $fmt: expr) => {
|
|
{
|
|
use std::io::Write;
|
|
let mut buf = Vec::<u8>::new();
|
|
writeln!(buf, $fmt)?;
|
|
tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
|
|
}
|
|
};
|
|
($dst: expr, $fmt: expr, $($arg: tt)*) => {
|
|
{
|
|
use std::io::Write;
|
|
let mut buf = Vec::<u8>::new();
|
|
writeln!(buf, $fmt, $( $arg )*)?;
|
|
tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
|
|
}
|
|
};
|
|
}
|
|
pub(crate) use async_writeln;
|
|
|
|
impl<T> FileAdapter for T
|
|
where
|
|
T: WritingFileAdapter,
|
|
{
|
|
fn adapt(
|
|
&self,
|
|
a: super::AdaptInfo,
|
|
detection_reason: &crate::matching::FileMatcher,
|
|
) -> Result<crate::adapted_iter::AdaptedFilesIterBox> {
|
|
let (w, r) = tokio::io::duplex(128 * 1024);
|
|
let d2 = detection_reason.clone();
|
|
let archive_recursion_depth = a.archive_recursion_depth + 1;
|
|
let filepath_hint = format!("{}.txt", a.filepath_hint.to_string_lossy());
|
|
let postprocess = a.postprocess;
|
|
let line_prefix = a.line_prefix.clone();
|
|
let config = a.config.clone();
|
|
let joiner = tokio::spawn(async move {
|
|
let x = d2;
|
|
T::adapt_write(a, &x, Box::pin(w)).await.map_err(to_io_err)
|
|
});
|
|
|
|
Ok(one_file(AdaptInfo {
|
|
is_real_file: false,
|
|
filepath_hint: filepath_hint.into(),
|
|
archive_recursion_depth,
|
|
config,
|
|
inp: Box::pin(r.chain(join_handle_to_stream(joiner))),
|
|
line_prefix,
|
|
postprocess,
|
|
}))
|
|
}
|
|
}
|