use super::super::err; use crate::Id; use serde::{ de::{self, Visitor}, Deserialize, Deserializer, Serialize, Serializer, }; use serde_json::Value; use std::{convert::TryFrom, fmt, num::ParseIntError, str::FromStr}; impl TryFrom<&Value> for Id { type Error = err::Event; fn try_from(v: &Value) -> Result { Ok(v.as_str().ok_or(err::Event::DynParse)?.parse()?) } } impl std::ops::Deref for Id { type Target = i64; fn deref(&self) -> &i64 { &self.0 } } impl FromStr for Id { type Err = ParseIntError; fn from_str(s: &str) -> Result { Ok(Self(s.parse()?)) } } impl fmt::Display for Id { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", self.0) } } impl Serialize for Id { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&format!("{}", self.0)) } } impl<'de> Deserialize<'de> for Id { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_string(IdVisitor) } } struct IdVisitor; impl<'de> Visitor<'de> for IdVisitor { type Value = Id; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a string that can be parsed into an i64") } fn visit_str(self, value: &str) -> Result { match value.parse() { Ok(n) => Ok(Id(n)), Err(e) => Err(E::custom(format!("could not parse: {}", e))), } } fn visit_string(self, value: String) -> Result { match value.parse() { Ok(n) => Ok(Id(n)), Err(e) => Err(E::custom(format!("could not parse: {}", e))), } } }