diff --git a/src/api/firewall/models.rs b/src/api/firewall/models.rs index 694d70f..238702c 100644 --- a/src/api/firewall/models.rs +++ b/src/api/firewall/models.rs @@ -408,12 +408,22 @@ impl<'de> Deserialize<'de> for PortRange { let value: &str = Deserialize::deserialize(deserializer)?; + // Handle range with dash (e.g., "80-90") if let Some((start, end)) = value.split_once('-') { let start = start.parse::().map_err(D::Error::custom)?; let end = end.parse::().map_err(D::Error::custom)?; Ok(PortRange(RangeInclusive::new(start, end))) - } else { + } + // Handle comma-separated ports - use first port only for now + // TODO: This is a limitation - API can return multiple discrete ports but PortRange only supports ranges + else if let Some((first, _rest)) = value.split_once(',') { + let port = first.parse::().map_err(D::Error::custom)?; + + Ok(PortRange(RangeInclusive::new(port, port))) + } + // Handle single port + else { let port = value.parse::().map_err(D::Error::custom)?; Ok(PortRange(RangeInclusive::new(port, port))) diff --git a/src/api/firewall/serde.rs b/src/api/firewall/serde.rs index 218f8ec..632ce46 100644 --- a/src/api/firewall/serde.rs +++ b/src/api/firewall/serde.rs @@ -58,6 +58,10 @@ impl From for InternalFirewallTemplateConfig { #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct InternalFirewall { + #[serde(skip_serializing_if = "Option::is_none")] + pub server_ip: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub server_number: Option, pub status: State, pub filter_ipv6: bool, #[serde(rename = "whitelist_hos")]