Skip to main content

prns_config/reference/
interface_type.rs

1use super::keys::interface as interface_key;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum InterfaceKind {
5    Auto,
6    TcpClient,
7    TcpServer,
8    Udp,
9    Serial,
10    Kiss,
11    Ax25Kiss,
12    Rnode,
13    RnodeMulti,
14    Pipe,
15    Backbone,
16    BackboneClient,
17    I2p,
18    Weave,
19    PrnsUsbAuto,
20    PrnsBluetoothAuto,
21    PrnsWebSocketClient,
22    PrnsWebSocketServer,
23}
24
25impl InterfaceKind {
26    pub const CANONICAL_NAMES: &[&str] = &[
27        "AutoInterface",
28        "TCPClientInterface",
29        "TCPServerInterface",
30        "UDPInterface",
31        "SerialInterface",
32        "KISSInterface",
33        "AX25KISSInterface",
34        "RNodeInterface",
35        "RNodeMultiInterface",
36        "PipeInterface",
37        "BackboneInterface",
38        "BackboneClientInterface",
39        "I2PInterface",
40        "WeaveInterface",
41        "PrnsUsbAuto",
42        "PrnsBluetoothAuto",
43        "PrnsWebSocketClient",
44        "PrnsWebSocketServer",
45    ];
46
47    pub fn parse(value: &str) -> Option<Self> {
48        match value {
49            "AutoInterface" => Some(Self::Auto),
50            "TCPClientInterface" => Some(Self::TcpClient),
51            "TCPServerInterface" => Some(Self::TcpServer),
52            "UDPInterface" => Some(Self::Udp),
53            "SerialInterface" => Some(Self::Serial),
54            "KISSInterface" => Some(Self::Kiss),
55            "AX25KISSInterface" => Some(Self::Ax25Kiss),
56            "RNodeInterface" => Some(Self::Rnode),
57            "RNodeMultiInterface" => Some(Self::RnodeMulti),
58            "PipeInterface" => Some(Self::Pipe),
59            "BackboneInterface" => Some(Self::Backbone),
60            "BackboneClientInterface" => Some(Self::BackboneClient),
61            "I2PInterface" => Some(Self::I2p),
62            "WeaveInterface" => Some(Self::Weave),
63            _ => Self::parse_prns(value),
64        }
65    }
66
67    pub const fn canonical_name(self) -> &'static str {
68        match self {
69            Self::Auto => "AutoInterface",
70            Self::TcpClient => "TCPClientInterface",
71            Self::TcpServer => "TCPServerInterface",
72            Self::Udp => "UDPInterface",
73            Self::Serial => "SerialInterface",
74            Self::Kiss => "KISSInterface",
75            Self::Ax25Kiss => "AX25KISSInterface",
76            Self::Rnode => "RNodeInterface",
77            Self::RnodeMulti => "RNodeMultiInterface",
78            Self::Pipe => "PipeInterface",
79            Self::Backbone => "BackboneInterface",
80            Self::BackboneClient => "BackboneClientInterface",
81            Self::I2p => "I2PInterface",
82            Self::Weave => "WeaveInterface",
83            Self::PrnsUsbAuto => "PrnsUsbAuto",
84            Self::PrnsBluetoothAuto => "PrnsBluetoothAuto",
85            Self::PrnsWebSocketClient => "PrnsWebSocketClient",
86            Self::PrnsWebSocketServer => "PrnsWebSocketServer",
87        }
88    }
89
90    fn parse_prns(value: &str) -> Option<Self> {
91        if ["PrnsUsbAuto", "PrnsUsbAutoInterface"]
92            .iter()
93            .any(|candidate| value.eq_ignore_ascii_case(candidate))
94        {
95            return Some(Self::PrnsUsbAuto);
96        }
97        if [
98            "PrnsBluetoothAuto",
99            "PrnsBluetoothAutoInterface",
100            "PrnsBleAuto",
101            "PrnsBleAutoInterface",
102        ]
103        .iter()
104        .any(|candidate| value.eq_ignore_ascii_case(candidate))
105        {
106            return Some(Self::PrnsBluetoothAuto);
107        }
108        if ["PrnsWebSocketClient", "PrnsWebSocketClientInterface"]
109            .iter()
110            .any(|candidate| value.eq_ignore_ascii_case(candidate))
111        {
112            return Some(Self::PrnsWebSocketClient);
113        }
114        if ["PrnsWebSocketServer", "PrnsWebSocketServerInterface"]
115            .iter()
116            .any(|candidate| value.eq_ignore_ascii_case(candidate))
117        {
118            return Some(Self::PrnsWebSocketServer);
119        }
120        None
121    }
122
123    pub const fn cli_name(self) -> &'static str {
124        match self {
125            Self::Auto => "auto-wifi",
126            Self::TcpClient => "tcp-client",
127            Self::TcpServer => "tcp-server",
128            Self::Udp => "udp",
129            Self::Serial => "serial",
130            Self::Kiss => "kiss",
131            Self::Ax25Kiss => "ax25-kiss",
132            Self::Rnode => "rnode",
133            Self::RnodeMulti => "rnode-multi",
134            Self::Pipe => "pipe",
135            Self::Backbone => "backbone-server",
136            Self::BackboneClient => "backbone-client",
137            Self::I2p => "i2p",
138            Self::Weave => "weave",
139            Self::PrnsUsbAuto => "usb-auto",
140            Self::PrnsBluetoothAuto => "bluetooth-auto",
141            Self::PrnsWebSocketClient => "websocket-client",
142            Self::PrnsWebSocketServer => "websocket-server",
143        }
144    }
145
146    pub fn parse_cli(value: &str) -> Option<Self> {
147        let normalized = value.trim().to_ascii_lowercase();
148        match normalized.as_str() {
149            "auto" | "auto-wifi" | "wifi-auto" => Some(Self::Auto),
150            "tcp-client" => Some(Self::TcpClient),
151            "tcp-server" => Some(Self::TcpServer),
152            "udp" => Some(Self::Udp),
153            "serial" => Some(Self::Serial),
154            "kiss" => Some(Self::Kiss),
155            "ax25-kiss" | "ax25" => Some(Self::Ax25Kiss),
156            "rnode" => Some(Self::Rnode),
157            "rnode-multi" => Some(Self::RnodeMulti),
158            "pipe" => Some(Self::Pipe),
159            "backbone" | "backbone-server" => Some(Self::Backbone),
160            "backbone-client" => Some(Self::BackboneClient),
161            "i2p" => Some(Self::I2p),
162            "weave" => Some(Self::Weave),
163            "usb" | "usb-auto" => Some(Self::PrnsUsbAuto),
164            "bluetooth" | "bluetooth-auto" | "ble" | "ble-auto" => Some(Self::PrnsBluetoothAuto),
165            "websocket-client" | "ws-client" => Some(Self::PrnsWebSocketClient),
166            "websocket-server" | "ws-server" => Some(Self::PrnsWebSocketServer),
167            _ => Self::parse(value),
168        }
169    }
170
171    pub fn accepts_setting(self, key: &str) -> bool {
172        if interface_key::COMMON.contains(&key) {
173            return true;
174        }
175        let medium = match self {
176            Self::Auto => interface_key::AUTO,
177            Self::TcpClient => interface_key::TCP_CLIENT,
178            Self::TcpServer => interface_key::TCP_SERVER,
179            Self::Udp => interface_key::UDP,
180            Self::Serial => interface_key::SERIAL,
181            Self::Kiss => interface_key::KISS,
182            Self::Ax25Kiss => interface_key::AX25_KISS,
183            Self::Rnode => interface_key::RNODE,
184            Self::RnodeMulti => interface_key::RNODE_MULTI,
185            Self::Pipe => interface_key::PIPE,
186            Self::Backbone | Self::BackboneClient => interface_key::BACKBONE,
187            Self::I2p => interface_key::I2P,
188            Self::Weave => interface_key::WEAVE,
189            Self::PrnsUsbAuto | Self::PrnsBluetoothAuto => &[],
190            Self::PrnsWebSocketClient => interface_key::PRNS_WEBSOCKET_CLIENT,
191            Self::PrnsWebSocketServer => interface_key::PRNS_WEBSOCKET_SERVER,
192        };
193        medium.contains(&key)
194    }
195}
196
197pub(super) use InterfaceKind as InterfaceType;
198
199#[cfg(test)]
200mod tests {
201    use super::InterfaceKind;
202
203    #[test]
204    fn prns_names_normalize_without_relaxing_stock_names() {
205        for alias in [
206            "PrnsUsbAuto",
207            "prnsusbauto",
208            "PRNSUSBAUTOINTERFACE",
209            "PrnsBluetoothAuto",
210            "prnsbleauto",
211            "PRNSBLEAUTOINTERFACE",
212            "prnswebsocketclient",
213            "PRNSWEBSOCKETCLIENTINTERFACE",
214            "prnswebsocketserver",
215            "PRNSWEBSOCKETSERVERINTERFACE",
216        ] {
217            assert!(InterfaceKind::parse(alias).is_some(), "{alias}");
218        }
219        assert_eq!(InterfaceKind::parse("autointerface"), None);
220    }
221}