use std::fmt::{Display, Formatter};
use std::num::ParseFloatError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum PriorityError {
#[error("parse float error: {0}")]
Parse(#[from] ParseFloatError),
#[error("range error: [0.0, 1.0]")]
Range,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Priority(f32);
impl Priority {
pub fn new(priority: f32) -> Result<Self, PriorityError> {
match priority {
x if (0.0..=1.0).contains(&priority) => Ok(Self(x)),
_ => Err(PriorityError::Range),
}
}
pub fn new_fallback(priority: f32) -> Self {
Self(priority.max(0.0).min(1.0))
}
pub fn parse(priority: &str) -> Result<Self, PriorityError> {
let priority = priority.parse::<f32>()?;
Self::new(priority)
}
pub fn as_inner(&self) -> f32 {
self.0
}
pub const AVG: Self = Self(0.5);
pub const MIN: Self = Self(0.0);
pub const MAX: Self = Self(1.0);
}
impl Default for Priority {
fn default() -> Self {
Self::AVG.clone()
}
}
impl Display for Priority {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(format!("{:.1}", self.0).as_str(), f)
}
}
impl TryFrom<&str> for Priority {
type Error = PriorityError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
Self::parse(value)
}
}