aboutsummaryrefslogtreecommitdiff
path: root/src/blocking.rs
blob: 7cc90d352a39199b877384e55f1ec5232ebe2744 (plain) (blame)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Blocking wrappers around the asynchronous API.
//!
//! All functions except for members of the tunnel module internally use their
//! async counterparts inside a temporary tokio runtime.
//! Tunnels are already synchronous.
//!
//! Consult the async modules for documentation.

#[cfg(feature = "tunnel")]
pub use crate::tunnel;

/// A blocking wrapper around the async [`crate::Connection`].
#[derive(Debug)]
pub struct Connection {
    rt: tokio::runtime::Runtime,
    conn: crate::Connection,
}

impl Connection {
    /// Creates a new blocking wrapper around [`crate::Connection`].
    pub fn new() -> crate::Result<Self> {
        let rt = tokio::runtime::Runtime::new()?;

        Ok(Self {
            conn: rt.block_on(crate::Connection::new())?,
            rt,
        })
    }
}

macro_rules! blockify {
    ($blk:ident) => {
        pub fn $blk(&self) -> crate::Result<()> {
            self.rt.block_on(self.conn.$blk())
        }
    };
    ($blk:ident, $($v:tt: $t:ty),*) => {
        pub fn $blk(&self, $($v: $t),*) -> crate::Result<()> {
            self.rt.block_on(self.conn.$blk($($v),*))
        }
    };
    ($blk:ident -> $ret:ty, $($v:tt: $t:ty),*) => {
        pub fn $blk(&self, $($v: $t),*) -> crate::Result<$ret> {
            self.rt.block_on(self.conn.$blk($($v),*))
        }
    };
}

#[cfg(feature = "addr")]
pub mod addr {
    use super::Connection;

    use std::net::IpAddr;

    use futures::TryStreamExt;

    impl Connection {
        blockify!(address_flush, link: String);
        blockify!(address_flush4, link: String);
        blockify!(address_flush6, link: String);
        blockify!(address_flush6_global);
        blockify!(address_add, link: String, addr: IpAddr, prefix_len: u8);
        blockify!(address_add_link_local, link: String, addr: IpAddr, prefix_len: u8);

        pub fn address_get(&self, link: String) -> crate::Result<Vec<IpAddr>> {
            self.rt
                .block_on(async { self.conn.address_get(link).await?.try_collect().await })
        }
    }
}

#[cfg(feature = "status")]
pub mod link {
    use super::Connection;

    impl Connection {
        #[cfg(feature = "link")]
        blockify!(link_set, link: String, state: bool);
        #[cfg(feature = "link")]
        blockify!(link_set_mtu, link: String, mtu: u32);
        #[cfg(feature = "link")]
        blockify!(link_add_vlan, link: String, parent: String, vlan_id: u16);
        #[cfg(feature = "link")]
        blockify!(link_add_wireguard, link: String);
        #[cfg(feature = "link")]
        blockify!(link_delete, link: String);

        blockify!(link_is_up -> bool, link: String);
        blockify!(link_wait_up, link: String);
        blockify!(link_exists -> bool, link: String);
        blockify!(link_wait_exists, link: String);
        blockify!(link_index -> u32, link: String);
    }
}

#[cfg(feature = "route")]
pub mod route {
    use super::Connection;

    use crate::route::{Route4, Route6};

    impl Connection {
        blockify!(route_flush4, link: String);
        blockify!(route_flush6, link: String);
        blockify!(route_flush, link: String);
        blockify!(route_add4, r: Route4);
        blockify!(route_add6, r: Route6);
    }
}