use std::convert::TryFrom;
use serde::{Deserialize, Serialize};
use super::super::{
NmError,
connection::{DBUS_ASV_SIGNATURE, DbusDictionary},
};
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
#[serde(try_from = "DbusDictionary")]
#[non_exhaustive]
pub struct NmIpRoute {
pub dest: Option<String>,
pub prefix: Option<u32>,
pub next_hop: Option<String>,
pub src: Option<String>,
pub table: Option<u32>,
pub metric: Option<u32>,
pub weight: Option<u32>,
pub route_type: Option<String>,
pub cwnd: Option<u32>,
pub lock_cwnd: Option<bool>,
pub initcwnd: Option<u32>,
pub initrwnd: Option<u32>,
pub mtu: Option<u32>,
pub lock_mtu: Option<bool>,
pub quickack: Option<bool>,
pub advmss: Option<u32>,
_other: DbusDictionary,
}
impl TryFrom<DbusDictionary> for NmIpRoute {
type Error = NmError;
fn try_from(mut v: DbusDictionary) -> Result<Self, Self::Error> {
let mut weight = _from_map!(v, "weight", u32::try_from)?;
if let Some(weight_num) = weight
&& weight_num == 0
{
weight = None;
}
Ok(Self {
dest: _from_map!(v, "dest", String::try_from)?,
prefix: _from_map!(v, "prefix", u32::try_from)?,
next_hop: _from_map!(v, "next-hop", String::try_from)?,
src: _from_map!(v, "src", String::try_from)?,
table: _from_map!(v, "table", u32::try_from)?,
metric: _from_map!(v, "metric", u32::try_from)?,
weight,
route_type: _from_map!(v, "type", String::try_from)?,
cwnd: _from_map!(v, "cwnd", u32::try_from)?,
lock_cwnd: _from_map!(v, "lock-cwnd", bool::try_from)?,
initcwnd: _from_map!(v, "initcwnd", u32::try_from)?,
initrwnd: _from_map!(v, "initrwnd", u32::try_from)?,
mtu: _from_map!(v, "mtu", u32::try_from)?,
lock_mtu: _from_map!(v, "lock-mtu", bool::try_from)?,
quickack: _from_map!(v, "quickack", bool::try_from)?,
advmss: _from_map!(v, "advmss", u32::try_from)?,
_other: v,
})
}
}
impl NmIpRoute {
fn to_value(&self) -> Result<zvariant::Value<'_>, NmError> {
let mut ret = zvariant::Dict::new(
&zvariant::Signature::Str,
&zvariant::Signature::Variant,
);
if let Some(v) = &self.dest {
ret.append(
zvariant::Value::new("dest"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.prefix {
ret.append(
zvariant::Value::new("prefix"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.next_hop {
ret.append(
zvariant::Value::new("next-hop"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.src {
ret.append(
zvariant::Value::new("src"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.table {
ret.append(
zvariant::Value::new("table"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.metric {
ret.append(
zvariant::Value::new("metric"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.weight {
ret.append(
zvariant::Value::new("weight"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.route_type {
ret.append(
zvariant::Value::new("type"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.cwnd {
ret.append(
zvariant::Value::new("cwnd"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.lock_cwnd {
ret.append(
zvariant::Value::new("lock-cwnd"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.initcwnd {
ret.append(
zvariant::Value::new("initcwnd"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.initrwnd {
ret.append(
zvariant::Value::new("initrwnd"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.mtu {
ret.append(
zvariant::Value::new("mtu"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.lock_mtu {
ret.append(
zvariant::Value::new("lock-mtu"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.quickack {
ret.append(
zvariant::Value::new("quickack"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
if let Some(v) = &self.advmss {
ret.append(
zvariant::Value::new("advmss"),
zvariant::Value::new(zvariant::Value::new(v)),
)?;
}
for (key, value) in self._other.iter() {
ret.append(
zvariant::Value::new(key.as_str()),
zvariant::Value::from(value.clone()),
)?;
}
Ok(zvariant::Value::Dict(ret))
}
}
pub(crate) fn parse_nm_ip_route_data(
value: zvariant::OwnedValue,
) -> Result<Vec<NmIpRoute>, NmError> {
let mut routes = Vec::new();
for nm_route_value in <Vec<DbusDictionary>>::try_from(value)? {
routes.push(NmIpRoute::try_from(nm_route_value)?);
}
Ok(routes)
}
pub(crate) fn nm_ip_routes_to_value(
nm_routes: &[NmIpRoute],
) -> Result<zvariant::Value<'_>, NmError> {
let mut route_values = zvariant::Array::new(DBUS_ASV_SIGNATURE);
for nm_route in nm_routes {
route_values.append(nm_route.to_value()?)?;
}
Ok(zvariant::Value::Array(route_values))
}