use log::debug;
use log::error;
use log::warn;
use lychee_lib::Request;
use lychee_lib::RequestError;
use std::fs;
use std::io::{self, Write};
use tokio_stream::StreamExt;
use crate::ExitCode;
use crate::verbosity::Verbosity;
use super::CommandParams;
pub(crate) async fn dump<S>(params: CommandParams<S>) -> lychee_lib::Result<ExitCode>
where
S: futures::Stream<Item = Result<Request, RequestError>>,
{
let requests = params.requests;
tokio::pin!(requests);
if let Some(out_file) = ¶ms.cfg.output {
fs::File::create(out_file)?;
}
let verbosity = params.cfg.verbose();
let mut writer = super::create_writer(params.cfg.output)?;
while let Some(request) = requests.next().await {
if let Err(e @ RequestError::UserInputContent { .. }) = request {
return Err(e.into_error());
}
let mut request = match request {
Ok(x) => x,
Err(e) => {
warn!("{e}");
continue;
}
};
params
.client
.remap(&mut request.uri)?
.inspect(|r| debug!("Remapping {r}"));
let excluded = params.client.is_excluded(&request.uri);
if excluded && verbosity.log_level() < log::Level::Info {
continue;
}
if let Err(e) = write(&mut writer, &request, &verbosity, excluded) {
if e.kind() != io::ErrorKind::BrokenPipe {
error!("{e}");
return Ok(ExitCode::UnexpectedFailure);
}
}
}
Ok(ExitCode::Success)
}
fn write(
writer: &mut Box<dyn Write>,
request: &Request,
verbosity: &Verbosity,
excluded: bool,
) -> io::Result<()> {
if request.uri.is_data() && verbosity.log_level() < log::Level::Info {
return Ok(());
}
let request = if verbosity.log_level() >= log::Level::Info {
request.to_string()
} else {
request.uri.to_string()
};
let out_str = if excluded {
format!("{request} [excluded]")
} else {
request
};
write_out(writer, &out_str)
}
fn write_out(writer: &mut Box<dyn Write>, out_str: &str) -> io::Result<()> {
writeln!(writer, "{out_str}")
}