Skip to main content

mock_igd/action/
types.rs

1//! UPnP IGD action type definitions.
2
3use std::net::IpAddr;
4
5/// Protocol type for port mappings.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum Protocol {
8    TCP,
9    UDP,
10}
11
12impl Protocol {
13    pub fn as_str(&self) -> &'static str {
14        match self {
15            Protocol::TCP => "TCP",
16            Protocol::UDP => "UDP",
17        }
18    }
19}
20
21impl std::fmt::Display for Protocol {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        write!(f, "{}", self.as_str())
24    }
25}
26
27/// UPnP IGD actions that can be matched against.
28#[derive(Debug, Clone)]
29pub enum Action {
30    // WANIPConnection actions
31    /// Get the external IP address of the gateway.
32    GetExternalIPAddress,
33
34    /// Get the connection status information.
35    GetStatusInfo,
36
37    /// Add a port mapping.
38    AddPortMapping(AddPortMappingParams),
39
40    /// Delete a port mapping.
41    DeletePortMapping(DeletePortMappingParams),
42
43    /// Get a port mapping entry by index.
44    GetGenericPortMappingEntry(GetGenericPortMappingEntryParams),
45
46    /// Get a specific port mapping entry.
47    GetSpecificPortMappingEntry(GetSpecificPortMappingEntryParams),
48
49    // WANCommonInterfaceConfig actions
50    /// Get common link properties.
51    GetCommonLinkProperties,
52
53    /// Get total bytes received.
54    GetTotalBytesReceived,
55
56    /// Get total bytes sent.
57    GetTotalBytesSent,
58
59    /// Match any action (wildcard).
60    Any,
61}
62
63impl Action {
64    /// Create an AddPortMapping action with matching parameters.
65    pub fn add_port_mapping() -> AddPortMappingBuilder {
66        AddPortMappingBuilder::default()
67    }
68
69    /// Create a DeletePortMapping action with matching parameters.
70    pub fn delete_port_mapping() -> DeletePortMappingBuilder {
71        DeletePortMappingBuilder::default()
72    }
73
74    /// Create a GetGenericPortMappingEntry action with matching parameters.
75    pub fn get_generic_port_mapping_entry() -> GetGenericPortMappingEntryBuilder {
76        GetGenericPortMappingEntryBuilder::default()
77    }
78
79    /// Create a GetSpecificPortMappingEntry action with matching parameters.
80    pub fn get_specific_port_mapping_entry() -> GetSpecificPortMappingEntryBuilder {
81        GetSpecificPortMappingEntryBuilder::default()
82    }
83
84    /// Match any action.
85    pub fn any() -> Self {
86        Action::Any
87    }
88}
89
90// =============================================================================
91// AddPortMapping
92// =============================================================================
93
94/// Parameters for matching AddPortMapping requests.
95#[derive(Debug, Clone, Default)]
96pub struct AddPortMappingParams {
97    pub external_port: Option<u16>,
98    pub protocol: Option<Protocol>,
99    pub internal_port: Option<u16>,
100    pub internal_client: Option<IpAddr>,
101    pub description: Option<String>,
102}
103
104/// Builder for AddPortMapping matching parameters.
105#[derive(Debug, Clone, Default)]
106pub struct AddPortMappingBuilder {
107    params: AddPortMappingParams,
108}
109
110impl AddPortMappingBuilder {
111    pub fn with_external_port(mut self, port: u16) -> Self {
112        self.params.external_port = Some(port);
113        self
114    }
115
116    pub fn with_protocol(mut self, protocol: Protocol) -> Self {
117        self.params.protocol = Some(protocol);
118        self
119    }
120
121    pub fn with_internal_port(mut self, port: u16) -> Self {
122        self.params.internal_port = Some(port);
123        self
124    }
125
126    pub fn with_internal_client(mut self, client: IpAddr) -> Self {
127        self.params.internal_client = Some(client);
128        self
129    }
130
131    pub fn with_description(mut self, desc: impl Into<String>) -> Self {
132        self.params.description = Some(desc.into());
133        self
134    }
135
136    pub fn build(self) -> Action {
137        Action::AddPortMapping(self.params)
138    }
139}
140
141impl From<AddPortMappingBuilder> for Action {
142    fn from(builder: AddPortMappingBuilder) -> Self {
143        builder.build()
144    }
145}
146
147// =============================================================================
148// DeletePortMapping
149// =============================================================================
150
151/// Parameters for matching DeletePortMapping requests.
152#[derive(Debug, Clone, Default)]
153pub struct DeletePortMappingParams {
154    pub external_port: Option<u16>,
155    pub protocol: Option<Protocol>,
156}
157
158/// Builder for DeletePortMapping matching parameters.
159#[derive(Debug, Clone, Default)]
160pub struct DeletePortMappingBuilder {
161    params: DeletePortMappingParams,
162}
163
164impl DeletePortMappingBuilder {
165    pub fn with_external_port(mut self, port: u16) -> Self {
166        self.params.external_port = Some(port);
167        self
168    }
169
170    pub fn with_protocol(mut self, protocol: Protocol) -> Self {
171        self.params.protocol = Some(protocol);
172        self
173    }
174
175    pub fn build(self) -> Action {
176        Action::DeletePortMapping(self.params)
177    }
178}
179
180impl From<DeletePortMappingBuilder> for Action {
181    fn from(builder: DeletePortMappingBuilder) -> Self {
182        builder.build()
183    }
184}
185
186// =============================================================================
187// GetGenericPortMappingEntry
188// =============================================================================
189
190/// Parameters for matching GetGenericPortMappingEntry requests.
191#[derive(Debug, Clone, Default)]
192pub struct GetGenericPortMappingEntryParams {
193    pub index: Option<u32>,
194}
195
196/// Builder for GetGenericPortMappingEntry matching parameters.
197#[derive(Debug, Clone, Default)]
198pub struct GetGenericPortMappingEntryBuilder {
199    params: GetGenericPortMappingEntryParams,
200}
201
202impl GetGenericPortMappingEntryBuilder {
203    pub fn with_index(mut self, index: u32) -> Self {
204        self.params.index = Some(index);
205        self
206    }
207
208    pub fn build(self) -> Action {
209        Action::GetGenericPortMappingEntry(self.params)
210    }
211}
212
213impl From<GetGenericPortMappingEntryBuilder> for Action {
214    fn from(builder: GetGenericPortMappingEntryBuilder) -> Self {
215        builder.build()
216    }
217}
218
219// =============================================================================
220// GetSpecificPortMappingEntry
221// =============================================================================
222
223/// Parameters for matching GetSpecificPortMappingEntry requests.
224#[derive(Debug, Clone, Default)]
225pub struct GetSpecificPortMappingEntryParams {
226    pub external_port: Option<u16>,
227    pub protocol: Option<Protocol>,
228}
229
230/// Builder for GetSpecificPortMappingEntry matching parameters.
231#[derive(Debug, Clone, Default)]
232pub struct GetSpecificPortMappingEntryBuilder {
233    params: GetSpecificPortMappingEntryParams,
234}
235
236impl GetSpecificPortMappingEntryBuilder {
237    pub fn with_external_port(mut self, port: u16) -> Self {
238        self.params.external_port = Some(port);
239        self
240    }
241
242    pub fn with_protocol(mut self, protocol: Protocol) -> Self {
243        self.params.protocol = Some(protocol);
244        self
245    }
246
247    pub fn build(self) -> Action {
248        Action::GetSpecificPortMappingEntry(self.params)
249    }
250}
251
252impl From<GetSpecificPortMappingEntryBuilder> for Action {
253    fn from(builder: GetSpecificPortMappingEntryBuilder) -> Self {
254        builder.build()
255    }
256}