use std::borrow::Cow;
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer};
#[derive(Debug, Clone)]
pub enum Id<'a> {
Null,
Str(Cow<'a, str>),
Int(i64),
Uint(u64),
Float(f64),
}
impl<'a> From<i64> for Id<'a> {
#[inline(always)]
fn from(id: i64) -> Self {
Self::Int(id)
}
}
impl<'a> From<u64> for Id<'a> {
#[inline(always)]
fn from(id: u64) -> Self {
Self::Uint(id)
}
}
impl<'a> From<f64> for Id<'a> {
#[inline(always)]
fn from(id: f64) -> Self {
Self::Float(id)
}
}
impl<'a> From<&'a str> for Id<'a> {
#[inline(always)]
fn from(id: &'a str) -> Self {
Self::Str(Cow::Borrowed(id))
}
}
impl<'a> From<String> for Id<'a> {
#[inline(always)]
fn from(id: String) -> Self {
Self::Str(Cow::Owned(id))
}
}
impl<'a> From<Cow<'a, str>> for Id<'a> {
#[inline(always)]
fn from(id: Cow<'a, str>) -> Self {
Self::Str(id)
}
}
impl<'a> Id<'a> {
pub fn reborrow<'b>(&'b self) -> Id<'b>
where
'b: 'a,
{
match *self {
Self::Null => Self::Null,
Self::Str(ref s) => Self::Str(Cow::Borrowed(s)),
Self::Int(i) => Self::Int(i),
Self::Uint(u) => Self::Uint(u),
Self::Float(f) => Self::Float(f),
}
}
}
impl<'a> Serialize for Id<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Self::Null => serializer.serialize_none(),
Self::Float(f) => serializer.serialize_f64(f),
Self::Str(ref s) => serializer.serialize_str(s),
Self::Int(i) => serializer.serialize_i64(i),
Self::Uint(u) => serializer.serialize_u64(u),
}
}
}
impl<'de, 'a> Deserialize<'de> for Id<'a>
where
'de: 'a,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct IdVisitor;
impl<'de> Visitor<'de> for IdVisitor {
type Value = crate::Id<'de>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a JSON-RPC 2.0 ID")
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Null)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Str(Cow::Borrowed(v)))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Str(Cow::Owned(v.to_owned())))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Str(Cow::Owned(v)))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Int(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Uint(v))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(crate::Id::Float(v))
}
}
deserializer.deserialize_option(IdVisitor)
}
}