greg 0.2.5

Simple Unobtrusive Date & Time library
Documentation
use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;

use serde::{
	Serialize,
	Deserialize,
	de::{self, Visitor}
};

use super::{
	DateTime,
	Date,
	Time
};


struct FromStrVisitor<T>{
	expect: &'static str,
	marker: PhantomData<T>
}

impl<T> FromStrVisitor<T> {
	pub fn expect(expect: &'static str) -> Self {
		let marker = PhantomData;
		Self { expect, marker }
	}
}

impl<T, E> Visitor<'_> for FromStrVisitor<T>
	where T: FromStr<Err = E>,
		E: fmt::Display
{
	type Value = T;

	fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
		formatter.write_str(self.expect)
	}
	fn visit_str<D>(self, value: &str) -> Result<Self::Value, D>
		where D: de::Error,
	{
		value.parse::<T>().map_err(D::custom)
	}
}

macro_rules! as_str {
	($t:ty, $e:literal) => {
		impl Serialize for $t {
			fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
				where S: serde::Serializer
			{
				serializer.serialize_str(&self.to_string())
			}
		}

		impl<'de> Deserialize<'de> for $t {
			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
				where D: serde::Deserializer<'de>
			{
				deserializer.deserialize_str(FromStrVisitor::expect($e))
			}
		}
	};
}
as_str!(DateTime, "a properly formatted Date & Time");
as_str!(Date, "a properly formatted Date");
as_str!(Time, "a properly formatted Time");