use std::sync::Arc;
use std::thread::{self, JoinHandle};
use serde::de::DeserializeOwned;
use structopt::StructOpt;
use crate::{AnyError, Spirit};
pub struct TerminateGuard<O, C>
where
C: DeserializeOwned + Send + Sync,
O: StructOpt,
{
spirit: Arc<Spirit<O, C>>,
bg: Option<JoinHandle<Result<(), AnyError>>>,
}
impl<O, C> TerminateGuard<O, C>
where
C: DeserializeOwned + Send + Sync,
O: StructOpt,
{
pub(crate) fn new(spirit: Arc<Spirit<O, C>>, bg: JoinHandle<Result<(), AnyError>>) -> Self {
Self {
spirit,
bg: Some(bg),
}
}
pub fn spirit(&self) -> &Arc<Spirit<O, C>> {
&self.spirit
}
}
impl<O, C> Drop for TerminateGuard<O, C>
where
C: DeserializeOwned + Send + Sync,
O: StructOpt,
{
fn drop(&mut self) {
self.spirit.terminate();
let result = self
.bg
.take()
.expect("Drop called multiple times?!? Missing the join handle")
.join();
if !thread::panicking() {
result
.expect("Spirit test thread panicked")
.expect("Test spirit terminated with an error");
}
}
}