Skip to main content

tanzim_validate/
percentage.rs

1use crate::error::{Error, ErrorKind};
2use crate::{Meta, Validator};
3use tanzim_value::{Value, ValueType};
4
5/// (`percentage` feature) Accepts a percentage: an integer in `0..=100`, or a float ratio in `0.0..=1.0`.
6#[derive(Debug, Clone, Default)]
7pub struct Percentage {
8    meta: Meta,
9}
10
11impl Percentage {
12    pub fn new() -> Self {
13        Self::default()
14    }
15
16    /// Attach human-facing metadata (name, description, examples, default, output conversion).
17    pub fn with_meta(mut self, meta: Meta) -> Self {
18        self.meta = meta;
19        self
20    }
21}
22
23crate::impl_meta_methods!(Percentage);
24
25impl Validator for Percentage {
26    fn meta(&self) -> &Meta {
27        &self.meta
28    }
29
30    fn meta_mut(&mut self) -> &mut Meta {
31        &mut self.meta
32    }
33
34    fn check(&self, value: &mut Value) -> Result<(), Error> {
35        match value {
36            Value::Int(number) => {
37                if (0..=100).contains(number) {
38                    Ok(())
39                } else {
40                    Err(Error::new(ErrorKind::Format {
41                        expected: "percentage in 0..=100",
42                    }))
43                }
44            }
45            Value::Float(number) => {
46                if (0.0..=1.0).contains(number) {
47                    Ok(())
48                } else {
49                    Err(Error::new(ErrorKind::Format {
50                        expected: "ratio in 0.0..=1.0",
51                    }))
52                }
53            }
54            other => Err(Error::new(ErrorKind::Type {
55                expected: ValueType::Float,
56                found: other.type_name(),
57            })),
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn int_and_ratio() {
68        assert!(Percentage::new().validate(&mut Value::Int(50)).is_ok());
69        assert!(Percentage::new().validate(&mut Value::Int(150)).is_err());
70        assert!(Percentage::new().validate(&mut Value::Float(0.5)).is_ok());
71        assert!(Percentage::new().validate(&mut Value::Float(1.5)).is_err());
72    }
73}