Skip to main content

batman_robin/model/
interface_selector.rs

1/// Selects a network interface either by interface name or by ifindex.
2#[derive(Clone, Debug, PartialEq, Eq, Default)]
3pub struct InterfaceSelector {
4    /// Selects the interface by name (for example, `"wlan0"`).
5    pub name: Option<String>,
6    /// Selects the interface by Linux interface index.
7    pub ifindex: Option<u32>,
8}
9
10impl InterfaceSelector {
11    /// Creates an empty selector.
12    pub fn new() -> Self {
13        Self {
14            name: None,
15            ifindex: None,
16        }
17    }
18
19    /// Creates a selector from an interface name.
20    pub fn with_name(name: impl Into<String>) -> Self {
21        Self {
22            name: Some(name.into()),
23            ifindex: None,
24        }
25    }
26
27    /// Creates a selector from an interface index.
28    pub const fn with_ifindex(ifindex: u32) -> Self {
29        Self {
30            name: None,
31            ifindex: Some(ifindex),
32        }
33    }
34}
35
36impl validator::Validate for InterfaceSelector {
37    fn validate(&self) -> Result<(), validator::ValidationErrors> {
38        let mut errors = validator::ValidationErrors::new();
39
40        if self.name.is_none() && self.ifindex.is_none() {
41            errors.add(
42                "interface_selector",
43                validator::ValidationError {
44                    code: std::borrow::Cow::from("at_least_one_field"),
45                    message: Some(std::borrow::Cow::from(
46                        "At least one of 'name' or 'ifindex' must be set",
47                    )),
48                    params: std::collections::HashMap::new(),
49                },
50            );
51        }
52
53        if let Some(name) = &self.name
54            && name.trim().is_empty()
55        {
56            errors.add(
57                "name",
58                validator::ValidationError {
59                    code: std::borrow::Cow::from("empty_name"),
60                    message: Some(std::borrow::Cow::from(
61                        "Interface selector name cannot be empty",
62                    )),
63                    params: std::collections::HashMap::new(),
64                },
65            );
66        }
67
68        if let Some(ifindex) = self.ifindex
69            && ifindex == 0
70        {
71            errors.add(
72                "ifindex",
73                validator::ValidationError {
74                    code: std::borrow::Cow::from("invalid_ifindex"),
75                    message: Some(std::borrow::Cow::from(
76                        "Interface selector ifindex must be greater than 0",
77                    )),
78                    params: std::collections::HashMap::new(),
79                },
80            );
81        }
82
83        if errors.is_empty() {
84            Ok(())
85        } else {
86            Err(errors)
87        }
88    }
89}