parallel_disk_usage/args/
fraction.rs1use derive_more::{AsRef, Deref, Display, Error, Into};
2use std::{
3 convert::{TryFrom, TryInto},
4 num::ParseFloatError,
5 str::FromStr,
6};
7
8#[derive(Debug, Display, Default, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, Into)]
10pub struct Fraction(f32);
11
12#[derive(Debug, Display, Error, Clone, Copy, PartialEq, Eq)]
14pub enum ConversionError {
15 #[display("greater than or equal to 1")]
17 UpperBound,
18 #[display("less than 0")]
20 LowerBound,
21 #[display("not a number")]
23 NotANumber,
24}
25
26impl Fraction {
27 pub fn new(value: f32) -> Result<Self, ConversionError> {
29 use ConversionError::*;
30 if value.is_nan() {
31 return Err(NotANumber);
32 }
33 if value >= 1.0 {
34 return Err(UpperBound);
35 }
36 if value < 0.0 {
37 return Err(LowerBound);
38 }
39 Ok(Fraction(value))
40 }
41}
42
43impl TryFrom<f32> for Fraction {
44 type Error = ConversionError;
45 fn try_from(value: f32) -> Result<Self, Self::Error> {
46 Fraction::new(value)
47 }
48}
49
50#[derive(Debug, Display, Error, Clone, PartialEq, Eq)]
52pub enum FromStrError {
53 ParseFloatError(ParseFloatError),
54 Conversion(ConversionError),
55}
56
57impl FromStr for Fraction {
58 type Err = FromStrError;
59 fn from_str(text: &str) -> Result<Self, Self::Err> {
60 text.parse::<f32>()
61 .map_err(FromStrError::ParseFloatError)?
62 .try_into()
63 .map_err(FromStrError::Conversion)
64 }
65}