pub mod ip { use serde::{Deserialize, Deserializer, Serializer, de::Error}; use std::{net::IpAddr, str::FromStr}; pub fn deserialize<'de, D>(de: D) -> Result where D: Deserializer<'de>, { IpAddr::from_str(&String::deserialize(de)?).map_err(Error::custom) } pub fn serialize(ip: &IpAddr, se: S) -> Result where S: Serializer, { se.serialize_str(ip.to_string().as_str()) } pub mod option { use super::*; pub fn deserialize<'de, D>(de: D) -> Result, D::Error> where D: Deserializer<'de>, { if let Some(str) = Option::::deserialize(de)? { Ok(Some(IpAddr::from_str(&str).map_err(Error::custom)?)) } else { Ok(None) } } pub fn serialize(ip: &Option, se: S) -> Result where S: Serializer, { if let Some(ref ip) = *ip { se.serialize_str(ip.to_string().as_str()) } else { se.serialize_none() } } } } pub mod mac { use crate::mac::MacAddress; use serde::{Deserialize, Deserializer, Serializer, de::Error}; use std::str::FromStr; pub fn deserialize<'de, D>(de: D) -> Result where D: Deserializer<'de>, { MacAddress::from_str(&String::deserialize(de)?).map_err(Error::custom) } pub fn serialize(mac: &MacAddress, se: S) -> Result where S: Serializer, { se.serialize_str(&mac.to_string()) } } pub mod links { use std::collections::HashMap; use serde::{Deserialize, Deserializer, Serializer, ser::SerializeSeq}; #[derive(Deserialize)] #[serde(untagged)] enum Inner { Vec(Vec<(String, String)>), Hash(HashMap), } pub fn deserialize<'de, D>(de: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(match Inner::deserialize(de)? { Inner::Vec(vec) => vec, Inner::Hash(hash) => hash.into_iter().collect(), }) } pub fn serialize(links: &Vec<(String, String)>, se: S) -> Result where S: Serializer, { let mut seq = se.serialize_seq(Some(links.len()))?; for link in links { seq.serialize_element(link)?; } seq.end() } }