summaryrefslogtreecommitdiffhomepage
path: root/talpid-routing/src/unix/macos/ip_map.rs
blob: 5d0ad4c61d087aff951fec06179fa30ebfcd8a25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use super::interface::Family;

/// A map where the key is [Family].
#[derive(Clone, Debug)]
pub struct IpMap<T> {
    v4: Option<T>,
    v6: Option<T>,
}

impl<T> IpMap<T> {
    pub const fn new() -> Self {
        Self { v4: None, v6: None }
    }

    pub fn get(&self, family: Family) -> Option<&T> {
        match family {
            Family::V4 => self.v4.as_ref(),
            Family::V6 => self.v6.as_ref(),
        }
    }

    /// Insert an option value and return the old value.
    pub fn set(&mut self, family: Family, value: Option<T>) -> Option<T> {
        let old_value = self.remove(family);
        match family {
            Family::V4 => self.v4 = value,
            Family::V6 => self.v6 = value,
        };
        old_value
    }

    /// Insert a value and return the old value.
    pub fn insert(&mut self, family: Family, value: T) -> Option<T> {
        match family {
            Family::V4 => self.v4.replace(value),
            Family::V6 => self.v6.replace(value),
        }
    }

    /// Remove a value and return it.
    pub fn remove(&mut self, family: Family) -> Option<T> {
        match family {
            Family::V4 => self.v4.take(),
            Family::V6 => self.v6.take(),
        }
    }

    pub fn len(&self) -> usize {
        self.iter().count()
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn iter(&self) -> impl Iterator<Item = (Family, &T)> {
        [(Family::V4, &self.v4), (Family::V6, &self.v6)]
            .into_iter()
            .flat_map(|(family, elem)| Some((family, elem.as_ref()?)))
    }

    pub fn drain(&mut self) -> impl Iterator<Item = (Family, T)> {
        [(Family::V4, self.v4.take()), (Family::V6, self.v6.take())]
            .into_iter()
            .flat_map(|(family, elem)| Some((family, elem?)))
    }
}