use tokio::task::JoinHandle;
pub(super) struct Outcome {
pub status: i32,
pub errors: Vec<String>,
}
pub(super) fn gather(result: anyhow::Result<i32>, cleanup: Vec<anyhow::Result<()>>) -> Outcome {
let (mut status, mut errors) = match result {
Ok(status) => (status, Vec::new()),
Err(error) => (1, vec![error.to_string()]),
};
errors.extend(
cleanup
.into_iter()
.filter_map(Result::err)
.map(|error| error.to_string()),
);
if status == 0 && !errors.is_empty() {
status = 1;
}
Outcome { status, errors }
}
pub(super) async fn stop<T>(task: &mut JoinHandle<T>, name: &str) -> anyhow::Result<Option<T>> {
if !task.is_finished() {
task.abort();
}
match task.await {
Ok(result) => Ok(Some(result)),
Err(error) if error.is_cancelled() => Ok(None),
Err(_) => Err(anyhow::anyhow!("{name}_panicked")),
}
}
#[cfg(test)]
#[path = "closing_tests.rs"]
mod tests;