Skip to main content

tanzim_validate/
cidr.rs

1use crate::error::{Error, ErrorKind};
2use crate::{Meta, Validator};
3use tanzim_value::{Value, ValueType};
4
5/// (`cidr` feature) Accepts a CIDR network such as `10.0.0.0/8` or `2001:db8::/32`.
6#[derive(Debug, Clone, Default)]
7pub struct Cidr {
8    meta: Meta,
9}
10
11impl Cidr {
12    pub fn new() -> Self {
13        Self {
14            meta: Meta::default(),
15        }
16    }
17
18    /// Attach human-facing metadata (name, description, examples, default, output conversion).
19    pub fn with_meta(mut self, meta: Meta) -> Self {
20        self.meta = meta;
21        self
22    }
23}
24
25crate::impl_meta_methods!(Cidr);
26
27impl Validator for Cidr {
28    fn meta(&self) -> &Meta {
29        &self.meta
30    }
31
32    fn meta_mut(&mut self) -> &mut Meta {
33        &mut self.meta
34    }
35
36    fn check(&self, value: &mut Value) -> Result<(), Error> {
37        let text = match value {
38            Value::String(text) => text,
39            other => {
40                return Err(Error::new(ErrorKind::Type {
41                    expected: ValueType::String,
42                    found: other.type_name(),
43                }));
44            }
45        };
46        match text.parse::<ipnet::IpNet>() {
47            Ok(_) => Ok(()),
48            Err(_) => Err(Error::new(ErrorKind::Format {
49                expected: "CIDR network",
50            })),
51        }
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn accepts_and_rejects() {
61        assert!(
62            Cidr::new()
63                .validate(&mut Value::String("10.0.0.0/8".into()))
64                .is_ok()
65        );
66        assert!(
67            Cidr::new()
68                .validate(&mut Value::String("10.0.0.0".into()))
69                .is_err()
70        );
71    }
72}