use crate::{parse_sleep_duration, Result};
use std::time::Duration;
pub fn smart_sleep<S>(input: S) -> Result<()>
where
S: Into<SleepInput>,
{
let sleep_input = input.into();
if sleep_input.should_sleep() {
let duration = sleep_input.to_duration()?;
std::thread::sleep(duration);
}
Ok(())
}
#[derive(Debug, Clone)]
pub enum SleepInput {
Number(isize),
Text(String),
Duration(Duration),
}
impl From<i32> for SleepInput {
fn from(value: i32) -> Self {
SleepInput::Number(value as isize)
}
}
impl From<isize> for SleepInput {
fn from(value: isize) -> Self {
SleepInput::Number(value)
}
}
impl From<&str> for SleepInput {
fn from(value: &str) -> Self {
SleepInput::Text(value.to_string())
}
}
impl From<String> for SleepInput {
fn from(value: String) -> Self {
SleepInput::Text(value)
}
}
impl From<Duration> for SleepInput {
fn from(value: Duration) -> Self {
SleepInput::Duration(value)
}
}
impl SleepInput {
pub fn should_sleep(&self) -> bool {
match self {
SleepInput::Number(n) => *n > 0,
SleepInput::Text(text) => {
if let Ok(n) = text.parse::<isize>() {
n > 0
} else {
true
}
}
SleepInput::Duration(duration) => !duration.is_zero(),
}
}
pub fn to_duration(&self) -> Result<Duration> {
match self {
SleepInput::Number(n) => {
if *n <= 0 {
Ok(Duration::ZERO)
} else {
Ok(Duration::from_millis(*n as u64))
}
}
SleepInput::Text(text) => parse_sleep_duration(text),
SleepInput::Duration(duration) => Ok(*duration),
}
}
}