#![deny(missing_docs)]
#![deny(unsafe_code)]
extern crate serde;
extern crate url;
use std::cmp::PartialEq;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::error::Error;
use serde::{Deserialize, Serialize, Serializer, Deserializer};
use url::{Url};
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer, for<'a> Ser<'a, T>: Serialize
{
Ser::new(value).serialize(serializer)
}
#[derive(Debug)]
pub struct Ser<'a, T: 'a>(&'a T);
impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
#[inline(always)]
pub fn new(value: &'a T) -> Self {
Ser(value)
}
}
impl<'a> Serialize for Ser<'a, Url> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_str(self.0.as_str())
}
}
pub fn deserialize<T, D>(deserializer: D) -> Result<T, D::Error>
where D: Deserializer, De<T>: Deserialize
{
De::deserialize(deserializer).map(De::into_inner)
}
#[derive(Debug)]
pub struct De<T>(T);
impl<T> De<T> where De<T>: serde::Deserialize {
#[inline(always)]
pub fn into_inner(self) -> T {
self.0
}
}
impl Deserialize for De<Url> {
fn deserialize<D>(deserializer: D) -> Result<De<Url>, D::Error> where D: Deserializer {
let string_representation: String = Deserialize::deserialize(deserializer)?;
Url::parse(&string_representation).map(De).map_err(|err| {
serde::de::Error::custom(err.description())
})
}
}
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct Serde<T>(pub T)
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize;
pub type SerdeUrl = Serde<Url>;
impl<T> Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
#[inline(always)]
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> fmt::Debug for Serde<T>
where T: fmt::Debug, De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.0.fmt(formatter)
}
}
impl<T> Deref for Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> DerefMut for Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T: PartialEq> PartialEq<T> for Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
fn eq(&self, other: &T) -> bool {
self.0 == *other
}
}
impl<T> Deserialize for Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer
{
De::deserialize(deserializer).map(De::into_inner).map(Serde)
}
}
impl<T> Serialize for Serde<T>
where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
Ser(&self.0).serialize(serializer)
}
}
#[test]
fn test_ser_de_url() {
extern crate serde_json;
let url = Url::parse("http://www.test.com/foo/bar?$param=bazz").unwrap();
let s = serde_json::to_string(&Ser::new(&url)).unwrap();
let new_url: Url = serde_json::from_str(&s).map(De::into_inner).unwrap();
assert_eq!(url, new_url);
}