unifly_api/command/requests/
network.rs1use serde::{Deserialize, Serialize};
2
3use crate::model::{EntityId, NetworkManagement, NetworkPurpose, WifiSecurityMode};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[allow(clippy::struct_excessive_bools)]
7pub struct CreateNetworkRequest {
8 pub name: String,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub vlan_id: Option<u16>,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub subnet: Option<String>,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub management: Option<NetworkManagement>,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub purpose: Option<NetworkPurpose>,
17 pub dhcp_enabled: bool,
18 pub enabled: bool,
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub dhcp_range_start: Option<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub dhcp_range_stop: Option<String>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub dhcp_lease_time: Option<u32>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub dns_servers: Option<Vec<String>>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub firewall_zone_id: Option<String>,
29 pub isolation_enabled: bool,
30 pub internet_access_enabled: bool,
31}
32
33#[derive(Debug, Clone, Default, Serialize, Deserialize)]
35pub struct DhcpUpdate {
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub dns_servers: Option<Vec<String>>,
38}
39
40#[derive(Debug, Clone, Default, Serialize, Deserialize)]
41#[allow(clippy::struct_excessive_bools)]
42pub struct UpdateNetworkRequest {
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub name: Option<String>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub vlan_id: Option<u16>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub subnet: Option<String>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub dhcp_enabled: Option<bool>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub enabled: Option<bool>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub isolation_enabled: Option<bool>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub internet_access_enabled: Option<bool>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub mdns_forwarding_enabled: Option<bool>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub ipv6_enabled: Option<bool>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub dhcp: Option<DhcpUpdate>,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[allow(clippy::struct_excessive_bools)]
67pub struct CreateWifiBroadcastRequest {
68 pub name: String,
69 #[serde(default)]
70 pub ssid: String,
71 pub security_mode: WifiSecurityMode,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub passphrase: Option<String>,
74 #[serde(default = "default_enabled")]
75 pub enabled: bool,
76 #[serde(skip_serializing_if = "Option::is_none", alias = "network")]
77 pub network_id: Option<EntityId>,
78 #[serde(default, alias = "hideName", alias = "hidden")]
79 pub hide_ssid: bool,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub broadcast_type: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 #[serde(alias = "broadcastingFrequenciesGHz", alias = "frequencies")]
84 pub frequencies_ghz: Option<Vec<f32>>,
85 #[serde(default)]
86 #[serde(alias = "bandSteeringEnabled")]
87 pub band_steering: bool,
88 #[serde(
89 default,
90 alias = "bssTransitionEnabled",
91 skip_serializing_if = "Option::is_none"
92 )]
93 pub fast_roaming: Option<bool>,
94}
95
96fn default_enabled() -> bool {
97 true
98}
99
100#[derive(Debug, Clone, Default, Serialize, Deserialize)]
101pub struct UpdateWifiBroadcastRequest {
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub name: Option<String>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub ssid: Option<String>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub security_mode: Option<WifiSecurityMode>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub passphrase: Option<String>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub enabled: Option<bool>,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 #[serde(alias = "hideName")]
114 pub hide_ssid: Option<bool>,
115}
116
117#[cfg(test)]
118mod tests {
119 use super::CreateWifiBroadcastRequest;
120
121 #[test]
122 fn create_wifi_broadcast_request_honors_alias_fields() {
123 let request: CreateWifiBroadcastRequest = serde_json::from_value(serde_json::json!({
124 "name": "Guest",
125 "ssid": "Guest",
126 "security_mode": "Open",
127 "enabled": true,
128 "hideName": true,
129 "bandSteeringEnabled": true,
130 "bssTransitionEnabled": true
131 }))
132 .expect("wifi broadcast request should deserialize");
133
134 assert!(request.hide_ssid);
135 assert!(request.band_steering);
136 assert_eq!(request.fast_roaming, Some(true));
137 }
138
139 #[test]
140 fn create_wifi_broadcast_request_honors_cli_style_aliases() {
141 let request: CreateWifiBroadcastRequest = serde_json::from_value(serde_json::json!({
142 "name": "Test",
143 "security_mode": "Wpa3Personal",
144 "passphrase": "test1234",
145 "hidden": true,
146 "fast_roaming": true,
147 "frequencies": [2.4]
148 }))
149 .expect("wifi broadcast request should deserialize with CLI-style aliases");
150
151 assert!(request.hide_ssid);
152 assert_eq!(request.fast_roaming, Some(true));
153 assert_eq!(request.frequencies_ghz, Some(vec![2.4]));
154 }
155}