use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::net::Ipv4Addr;
pub fn serialize<S>(ip: &Ipv4Addr, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if serializer.is_human_readable() {
ip.to_string().serialize(serializer)
} else {
serializer.serialize_u32(u32::from(*ip))
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Ipv4Addr, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
s.parse().map_err(serde::de::Error::custom)
} else {
u32::deserialize(deserializer).map(Ipv4Addr::from)
}
}
crate::serde::option_module!(std::net::Ipv4Addr);
#[cfg(test)]
mod tests {
use super::*;
use crate::rowbinary::serialize_row;
use bytes::BytesMut;
use serde::Serialize;
#[derive(Serialize)]
struct Row {
#[serde(with = "crate::serde::ipv4")]
ip: Ipv4Addr,
#[serde(with = "crate::serde::ipv4::option")]
opt: Option<Ipv4Addr>,
}
fn enc<T: Serialize>(v: &T) -> Vec<u8> {
let mut buf = BytesMut::new();
serialize_row(v, &mut buf).expect("serialize");
buf.to_vec()
}
#[test]
fn ipv4_is_a_little_endian_u32() {
let row = Row {
ip: Ipv4Addr::new(1, 2, 3, 4),
opt: Some(Ipv4Addr::new(127, 0, 0, 1)),
};
assert_eq!(enc(&row), [4, 3, 2, 1, 0, 1, 0, 0, 127]);
}
#[test]
fn nullable_ipv4_none_is_a_null_prefix() {
let row = Row {
ip: Ipv4Addr::new(0, 0, 0, 0),
opt: None,
};
assert_eq!(enc(&row), [0, 0, 0, 0, 1]);
}
#[test]
fn default_ipv4_serde_impl_is_documented_wrong_bytes() {
assert_eq!(enc(&Ipv4Addr::new(1, 2, 3, 4)), [1, 2, 3, 4]);
}
}