use std::{env::var, fmt::Debug, time::Duration};
pub use exit_strategy::ExitWaitStrategy;
pub use health_strategy::HealthWaitStrategy;
#[cfg(feature = "http_wait_plain")]
#[cfg_attr(docsrs, doc(cfg(feature = "http_wait_plain")))]
pub use http_strategy::HttpWaitStrategy;
pub use log_strategy::LogWaitStrategy;
use crate::core::{async_container::raw::RawContainer, client::Client, logs::LogSource};
pub(crate) mod cmd_wait;
pub(crate) mod exit_strategy;
pub(crate) mod health_strategy;
#[cfg(feature = "http_wait_plain")]
pub(crate) mod http_strategy;
pub(crate) mod log_strategy;
pub(crate) trait WaitStrategy {
async fn wait_until_ready(
self,
client: &Client,
container: &RawContainer,
) -> crate::core::error::Result<()>;
}
#[derive(Debug, Clone)]
pub enum WaitFor {
Nothing,
Log(LogWaitStrategy),
Duration { length: Duration },
Healthcheck(HealthWaitStrategy),
#[cfg(feature = "http_wait_plain")]
#[cfg_attr(docsrs, doc(cfg(feature = "http_wait_plain")))]
Http(Box<HttpWaitStrategy>),
Exit(ExitWaitStrategy),
}
impl WaitFor {
pub fn message_on_stdout(message: impl AsRef<[u8]>) -> WaitFor {
Self::log(LogWaitStrategy::new(LogSource::StdOut, message))
}
pub fn message_on_stderr(message: impl AsRef<[u8]>) -> WaitFor {
Self::log(LogWaitStrategy::new(LogSource::StdErr, message))
}
pub fn message_on_either_std(message: impl AsRef<[u8]>) -> WaitFor {
Self::log(LogWaitStrategy::new(LogSource::BothStd, message))
}
pub fn log(log_strategy: LogWaitStrategy) -> WaitFor {
WaitFor::Log(log_strategy)
}
pub fn healthcheck() -> WaitFor {
WaitFor::Healthcheck(HealthWaitStrategy::default())
}
#[cfg(feature = "http_wait_plain")]
#[cfg_attr(docsrs, doc(cfg(feature = "http_wait_plain")))]
pub fn http(http_strategy: HttpWaitStrategy) -> WaitFor {
WaitFor::Http(Box::new(http_strategy))
}
pub fn exit(exit_strategy: ExitWaitStrategy) -> WaitFor {
WaitFor::Exit(exit_strategy)
}
pub fn seconds(length: u64) -> WaitFor {
WaitFor::Duration {
length: Duration::from_secs(length),
}
}
pub fn millis(length: u64) -> WaitFor {
WaitFor::Duration {
length: Duration::from_millis(length),
}
}
pub fn millis_in_env_var(name: &'static str) -> WaitFor {
let additional_sleep_period = var(name).map(|value| value.parse());
(|| {
let length = additional_sleep_period.ok()?.ok()?;
Some(WaitFor::Duration {
length: Duration::from_millis(length),
})
})()
.unwrap_or(WaitFor::Nothing)
}
}
#[cfg(feature = "http_wait_plain")]
#[cfg_attr(docsrs, doc(cfg(feature = "http_wait_plain")))]
impl From<HttpWaitStrategy> for WaitFor {
fn from(value: HttpWaitStrategy) -> Self {
Self::Http(Box::new(value))
}
}
impl WaitStrategy for WaitFor {
async fn wait_until_ready(
self,
client: &Client,
container: &RawContainer,
) -> crate::core::error::Result<()> {
match self {
WaitFor::Log(strategy) => strategy.wait_until_ready(client, container).await?,
WaitFor::Duration { length } => {
tokio::time::sleep(length).await;
}
WaitFor::Healthcheck(strategy) => {
strategy.wait_until_ready(client, container).await?;
}
#[cfg(feature = "http_wait_plain")]
WaitFor::Http(strategy) => {
strategy.wait_until_ready(client, container).await?;
}
WaitFor::Exit(strategy) => {
strategy.wait_until_ready(client, container).await?;
}
WaitFor::Nothing => {}
}
Ok(())
}
}