use std::fmt;
use std::net::{AddrParseError, IpAddr, SocketAddr};
use std::ops::{Deref, DerefMut};
use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::constructor::JsonxConstructor;
use crate::datetime::DateTime;
use crate::tokens::{TOKEN_DATETIME, TOKEN_INT, TOKEN_IP, TOKEN_IPPORT, TOKEN_UINT};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct Bytes(pub Vec<u8>);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct Int(pub i64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct Uint(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Ip(pub IpAddr);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct IpPort(pub SocketAddr);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Datetime(pub DateTime);
impl Deref for Bytes {
type Target = Vec<u8>;
fn deref(&self) -> &Vec<u8> {
&self.0
}
}
impl DerefMut for Bytes {
fn deref_mut(&mut self) -> &mut Vec<u8> {
&mut self.0
}
}
macro_rules! wrapper_conversions {
($wrapper:ident, $inner:ty) => {
impl Deref for $wrapper {
type Target = $inner;
fn deref(&self) -> &$inner {
&self.0
}
}
impl DerefMut for $wrapper {
fn deref_mut(&mut self) -> &mut $inner {
&mut self.0
}
}
impl From<$inner> for $wrapper {
fn from(v: $inner) -> $wrapper {
$wrapper(v)
}
}
impl From<$wrapper> for $inner {
fn from(w: $wrapper) -> $inner {
w.0
}
}
};
}
wrapper_conversions!(Ip, IpAddr);
wrapper_conversions!(IpPort, SocketAddr);
wrapper_conversions!(Datetime, DateTime);
pub mod ip {
use std::net::IpAddr;
use serde::de;
use serde::{Deserializer, Serializer};
use crate::tokens::TOKEN_IP;
pub fn serialize<S: Serializer>(addr: &IpAddr, serializer: S) -> Result<S::Ok, S::Error> {
crate::constructor::serialize_constructor(serializer, TOKEN_IP, &addr.to_string())
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<IpAddr, D::Error> {
let arg = crate::constructor::deserialize_constructor(deserializer, TOKEN_IP)?;
arg.parse().map_err(de::Error::custom)
}
}
pub mod ipport {
use std::net::SocketAddr;
use serde::de;
use serde::{Deserializer, Serializer};
use crate::tokens::TOKEN_IPPORT;
pub fn serialize<S: Serializer>(addr: &SocketAddr, serializer: S) -> Result<S::Ok, S::Error> {
crate::constructor::serialize_constructor(serializer, TOKEN_IPPORT, &addr.to_string())
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<SocketAddr, D::Error> {
let arg = crate::constructor::deserialize_constructor(deserializer, TOKEN_IPPORT)?;
arg.parse().map_err(de::Error::custom)
}
}
impl Serialize for Bytes {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(&self.0)
}
}
impl<'de> Deserialize<'de> for Bytes {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct V;
impl<'de> Visitor<'de> for V {
type Value = Bytes;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a byte buffer")
}
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Bytes, E> {
Ok(Bytes(v.to_vec()))
}
fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Bytes, E> {
Ok(Bytes(v))
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Bytes, A::Error> {
let mut out = Vec::new();
while let Some(b) = seq.next_element::<u8>()? {
out.push(b);
}
Ok(Bytes(out))
}
}
deserializer.deserialize_byte_buf(V)
}
}
impl Serialize for Int {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_newtype_struct(TOKEN_INT, &self.0)
}
}
impl<'de> Deserialize<'de> for Int {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
i64::deserialize(deserializer).map(Int)
}
}
impl Serialize for Uint {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_newtype_struct(TOKEN_UINT, &self.0)
}
}
impl<'de> Deserialize<'de> for Uint {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
u64::deserialize(deserializer).map(Uint)
}
}
impl JsonxConstructor for Ip {
const TOKEN: &'static str = TOKEN_IP;
fn to_jsonx_arg(&self) -> String {
self.0.to_string()
}
fn from_jsonx_arg(arg: &str) -> Result<Self, String> {
arg.parse().map(Ip).map_err(|e: AddrParseError| e.to_string())
}
}
impl JsonxConstructor for IpPort {
const TOKEN: &'static str = TOKEN_IPPORT;
fn to_jsonx_arg(&self) -> String {
self.0.to_string()
}
fn from_jsonx_arg(arg: &str) -> Result<Self, String> {
arg.parse().map(IpPort).map_err(|e: AddrParseError| e.to_string())
}
}
impl JsonxConstructor for Datetime {
const TOKEN: &'static str = TOKEN_DATETIME;
fn to_jsonx_arg(&self) -> String {
crate::datetime::to_jsonx_string(&self.0)
}
fn from_jsonx_arg(arg: &str) -> Result<Self, String> {
crate::datetime::parse(arg).map(Datetime).map_err(|e| e.to_string())
}
}
macro_rules! delegate_serde_to_constructor {
($($wrapper:ident),* $(,)?) => {
$(
impl Serialize for $wrapper {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
crate::constructor::serialize(self, serializer)
}
}
impl<'de> Deserialize<'de> for $wrapper {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
crate::constructor::deserialize(deserializer)
}
}
)*
};
}
delegate_serde_to_constructor!(Ip, IpPort, Datetime);