nunc 0.2.0

WIP: time tracking application
Documentation
use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;

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

pub 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<'de, T, E> Visitor<'de> 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! serde_as_str {
	($t:ty, $e:literal) => {
		impl serde::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> serde::Deserialize<'de> for $t {
			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
				where D: serde::Deserializer<'de>
			{
				deserializer.deserialize_str(
					$crate::util::serde::FromStrVisitor::expect($e)
				)
			}
		}
	};
}