use log::error;
use lychee_lib::Request;
use lychee_lib::Result;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;
use tokio_stream::StreamExt;
use crate::verbosity::Verbosity;
use crate::ExitCode;
use super::CommandParams;
fn create_writer(output: Option<PathBuf>) -> Result<Box<dyn Write>> {
let out = if let Some(output) = output {
let out = fs::OpenOptions::new().append(true).open(output)?;
Box::new(out) as Box<dyn Write>
} else {
let out = io::stdout();
Box::new(out.lock()) as Box<dyn Write>
};
Ok(out)
}
pub(crate) async fn dump<S>(params: CommandParams<S>) -> Result<ExitCode>
where
S: futures::Stream<Item = Result<Request>>,
{
let requests = params.requests;
tokio::pin!(requests);
if let Some(out_file) = ¶ms.cfg.output {
fs::File::create(out_file)?;
}
let mut writer = create_writer(params.cfg.output)?;
while let Some(request) = requests.next().await {
let mut request = request?;
params.client.remap(&mut request.uri)?;
let excluded = params.client.is_excluded(&request.uri);
if excluded && params.cfg.verbose.log_level() < log::Level::Info {
continue;
}
if let Err(e) = write(&mut writer, &request, ¶ms.cfg.verbose, excluded) {
if e.kind() != io::ErrorKind::BrokenPipe {
error!("{e}");
return Ok(ExitCode::UnexpectedFailure);
}
}
}
Ok(ExitCode::Success)
}
pub(crate) async fn dump_inputs<S>(sources: S, output: Option<&PathBuf>) -> Result<ExitCode>
where
S: futures::Stream<Item = Result<String>>,
{
let sources = sources;
tokio::pin!(sources);
if let Some(out_file) = output {
fs::File::create(out_file)?;
}
let mut writer = create_writer(output.cloned())?;
while let Some(source) = sources.next().await {
let source = source?;
writeln!(writer, "{source}")?;
}
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}")
}