use std::sync::atomic::AtomicU64;
use super::InputImpl;
use anyhow::Result;
use libhaystack::{
units::{Unit, units_generated::MILLISECOND},
val::{Number, Value},
};
const DEFAULT_SLEEP_DUR: u64 = 200;
static SLEEP_DUR: AtomicU64 = AtomicU64::new(DEFAULT_SLEEP_DUR);
pub fn set_sleep_dur(dur: u64) {
SLEEP_DUR.store(dur, std::sync::atomic::Ordering::Relaxed);
}
pub fn get_sleep_dur() -> u64 {
SLEEP_DUR.load(std::sync::atomic::Ordering::Relaxed)
}
pub(super) fn input_as_float_or_default(input: &InputImpl) -> f64 {
input_as_number(input).map(|v| v.value).unwrap_or(0.0)
}
pub(super) fn input_as_number(input: &InputImpl) -> Option<Number> {
if let Some(Value::Number(val)) = input.val {
Some(val)
} else {
None
}
}
pub(super) fn input_as_number_in(input: &InputImpl, target: &'static Unit) -> Option<f64> {
let n = input_as_number(input)?;
match n.unit {
None => Some(n.value),
Some(u) if u == target => Some(n.value),
Some(u) => u.convert_to(n.value, target).ok(),
}
}
pub(super) fn input_as_number_matching(
input: &InputImpl,
target: Option<&'static Unit>,
) -> Option<f64> {
match target {
Some(u) => input_as_number_in(input, u),
None => input_as_number(input).map(|n| n.value),
}
}
pub(super) fn input_to_millis_or_default(dur: &Option<Value>) -> u64 {
if let Some(Value::Number(dur)) = dur {
if let Some(unit) = dur.unit {
match unit.convert_to(dur.value, &MILLISECOND) {
Ok(millis) => millis as u64,
Err(_) => DEFAULT_SLEEP_DUR,
}
} else {
dur.value as u64
}
} else {
DEFAULT_SLEEP_DUR
}
}
pub(super) fn convert_units(numbers: &[Number]) -> Result<Vec<Number>> {
if numbers.len() <= 1 {
Ok(numbers.to_vec())
} else if let Some(unit) = numbers
.iter()
.find_map(|n| if n.unit.is_some() { n.unit } else { None })
{
numbers
.iter()
.map(|n| {
if let Some(other_unit) = n.unit {
if other_unit != unit {
other_unit
.convert_to(n.value, unit)
.map_err(|err| anyhow::anyhow!(err))
.map(|v| Number {
value: v,
unit: Some(unit),
})
} else {
Ok(*n)
}
} else {
Ok(Number {
value: n.value,
unit: Some(unit),
})
}
})
.collect::<Result<Vec<Number>>>()
} else {
Ok(numbers.to_vec())
}
}