use alloc::string::ToString;
use base64::alphabet;
use base64::engine::{
general_purpose::STANDARD, DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig,
};
const LENIENT_CFG: GeneralPurposeConfig = GeneralPurposeConfig::new()
.with_decode_allow_trailing_bits(true)
.with_decode_padding_mode(DecodePaddingMode::Indifferent);
const STANDARD_LENIENT: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, LENIENT_CFG);
const URL_SAFE_LENIENT: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, LENIENT_CFG);
const MAX_PREALLOC_HINT: usize = 4096;
#[inline]
fn clamp_size_hint(hint: Option<usize>) -> usize {
hint.unwrap_or(0).min(MAX_PREALLOC_HINT)
}
pub trait ProtoElemJson: Sized {
fn serialize_proto_json<S: serde::Serializer>(v: &Self, s: S) -> Result<S::Ok, S::Error>;
fn deserialize_proto_json<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error>;
}
struct ProtoElemSer<'a, T>(&'a T);
impl<T: ProtoElemJson> serde::Serialize for ProtoElemSer<'_, T> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
T::serialize_proto_json(self.0, s)
}
}
struct ProtoElemSeed<T>(core::marker::PhantomData<T>);
impl<'de, T: ProtoElemJson> serde::de::DeserializeSeed<'de> for ProtoElemSeed<T> {
type Value = T;
fn deserialize<D: serde::Deserializer<'de>>(self, d: D) -> Result<T, D::Error> {
struct NoNull<T>(core::marker::PhantomData<T>);
impl<'de, T: ProtoElemJson> serde::de::Visitor<'de> for NoNull<T> {
type Value = T;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a non-null value")
}
fn visit_none<E: serde::de::Error>(self) -> Result<T, E> {
Err(E::custom(
"null is not a valid repeated-field element or map value",
))
}
fn visit_unit<E: serde::de::Error>(self) -> Result<T, E> {
Err(E::custom(
"null is not a valid repeated-field element or map value",
))
}
fn visit_some<D2: serde::Deserializer<'de>>(self, d: D2) -> Result<T, D2::Error> {
T::deserialize_proto_json(d)
}
}
d.deserialize_option(NoNull::<T>(core::marker::PhantomData))
}
}
macro_rules! proto_elem_json_delegate {
($ty:ty, $mod:ident) => {
impl ProtoElemJson for $ty {
fn serialize_proto_json<S: serde::Serializer>(
v: &Self,
s: S,
) -> Result<S::Ok, S::Error> {
$mod::serialize(v, s)
}
fn deserialize_proto_json<'de, D: serde::Deserializer<'de>>(
d: D,
) -> Result<Self, D::Error> {
$mod::deserialize(d)
}
}
};
}
pub mod proto_seq {
use super::{ProtoElemJson, ProtoElemSeed, ProtoElemSer};
use alloc::vec::Vec;
use serde::{Deserializer, Serializer};
pub fn serialize<T: ProtoElemJson, S: Serializer>(v: &[T], s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let mut seq = s.serialize_seq(Some(v.len()))?;
for elem in v {
seq.serialize_element(&ProtoElemSer(elem))?;
}
seq.end()
}
pub fn deserialize<'de, T: ProtoElemJson, D: Deserializer<'de>>(
d: D,
) -> Result<Vec<T>, D::Error> {
struct V<T>(core::marker::PhantomData<T>);
impl<'de, T: ProtoElemJson> serde::de::Visitor<'de> for V<T> {
type Value = Vec<T>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("an array or null")
}
fn visit_unit<E>(self) -> Result<Vec<T>, E> {
Ok(Vec::new())
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(
self,
mut seq: A,
) -> Result<Vec<T>, A::Error> {
let mut out = Vec::with_capacity(super::clamp_size_hint(seq.size_hint()));
while let Some(elem) =
seq.next_element_seed(ProtoElemSeed::<T>(core::marker::PhantomData))?
{
out.push(elem);
}
Ok(out)
}
}
d.deserialize_any(V::<T>(core::marker::PhantomData))
}
}
pub mod proto_map {
use super::{ProtoElemJson, ProtoElemSeed, ProtoElemSer};
use alloc::string::String;
use core::fmt::Display;
use core::hash::Hash;
use core::str::FromStr;
use serde::{Deserializer, Serializer};
struct DisplayKey<'a, K: ?Sized>(&'a K);
impl<K: Display + ?Sized> serde::Serialize for DisplayKey<'_, K> {
#[inline]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.collect_str(self.0)
}
}
pub fn serialize<K, V, S>(m: &crate::__private::HashMap<K, V>, s: S) -> Result<S::Ok, S::Error>
where
K: Display + Eq + Hash,
V: ProtoElemJson,
S: Serializer,
{
use serde::ser::SerializeMap;
let mut map = s.serialize_map(Some(m.len()))?;
for (k, v) in m {
map.serialize_entry(&DisplayKey(k), &ProtoElemSer(v))?;
}
map.end()
}
pub fn deserialize<'de, K, V, D>(d: D) -> Result<crate::__private::HashMap<K, V>, D::Error>
where
K: FromStr + Eq + Hash,
K::Err: Display,
V: ProtoElemJson,
D: Deserializer<'de>,
{
struct Vis<K, V>(core::marker::PhantomData<(K, V)>);
impl<'de, K, V> serde::de::Visitor<'de> for Vis<K, V>
where
K: FromStr + Eq + Hash,
K::Err: Display,
V: ProtoElemJson,
{
type Value = crate::__private::HashMap<K, V>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a JSON object with string keys, or null")
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::new();
while let Some(key) = map.next_key::<String>()? {
let k = K::from_str(&key).map_err(|e| {
serde::de::Error::custom(alloc::format!("invalid map key '{key}': {e}"))
})?;
let v = map.next_value_seed(ProtoElemSeed::<V>(core::marker::PhantomData))?;
out.insert(k, v);
}
Ok(out)
}
}
d.deserialize_any(Vis::<K, V>(core::marker::PhantomData))
}
}
pub mod proto_bool {
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &bool, s: S) -> Result<S::Ok, S::Error> {
s.serialize_bool(*value)
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<bool, D::Error> {
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = bool;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a boolean or null")
}
fn visit_unit<E>(self) -> Result<bool, E> {
Ok(false)
}
fn visit_bool<E>(self, v: bool) -> Result<bool, E> {
Ok(v)
}
}
d.deserialize_any(V)
}
}
pub mod proto_string {
use alloc::string::ToString;
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &str, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(value)
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<alloc::string::String, D::Error> {
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = alloc::string::String;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a string or null")
}
fn visit_unit<E>(self) -> Result<alloc::string::String, E> {
Ok(alloc::string::String::new())
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<alloc::string::String, E> {
Ok(v.to_string())
}
fn visit_string<E>(self, v: alloc::string::String) -> Result<alloc::string::String, E> {
Ok(v)
}
}
d.deserialize_any(V)
}
}
pub mod proto_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &crate::EnumValue<E>,
s: S,
) -> Result<S::Ok, S::Error> {
serde::Serialize::serialize(value, s)
}
pub fn deserialize<'de, E: crate::Enumeration, D: Deserializer<'de>>(
d: D,
) -> Result<crate::EnumValue<E>, D::Error> {
struct V<E>(core::marker::PhantomData<E>);
impl<'de, E: crate::Enumeration> serde::de::Visitor<'de> for V<E> {
type Value = crate::EnumValue<E>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a protobuf enum name string, integer value, or null")
}
fn visit_unit<Err>(self) -> Result<crate::EnumValue<E>, Err> {
Ok(crate::EnumValue::from(0))
}
fn visit_i64<Err: serde::de::Error>(self, v: i64) -> Result<crate::EnumValue<E>, Err> {
let i = i32::try_from(v).map_err(|_| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Signed(v),
&"an integer in i32 range",
)
})?;
Ok(crate::EnumValue::from(i))
}
fn visit_u64<Err: serde::de::Error>(self, v: u64) -> Result<crate::EnumValue<E>, Err> {
let i = i32::try_from(v).map_err(|_| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Unsigned(v),
&"an integer in i32 range",
)
})?;
Ok(crate::EnumValue::from(i))
}
fn visit_str<Err: serde::de::Error>(self, v: &str) -> Result<crate::EnumValue<E>, Err> {
match E::from_proto_name(v) {
Some(e) => Ok(crate::EnumValue::from(e)),
None => {
if crate::json::ignore_unknown_enum_values() {
return Ok(crate::EnumValue::from(0));
}
Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(v),
&"a known enum variant name",
))
}
}
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
#[inline]
fn try_deserialize_enum<T: serde::de::DeserializeOwned>(
raw: serde_json::Value,
) -> Result<Option<T>, serde_json::Error> {
#[cfg(feature = "std")]
{
let ignore = crate::json::ignore_unknown_enum_values();
let strict = crate::json::JsonParseOptions {
ignore_unknown_enum_values: false,
..Default::default()
};
let result =
crate::json::with_json_parse_options(&strict, || serde_json::from_value::<T>(raw));
match result {
Ok(v) => Ok(Some(v)),
Err(_) if ignore => Ok(None),
Err(e) => Err(e),
}
}
#[cfg(not(feature = "std"))]
{
serde_json::from_value::<T>(raw).map(Some)
}
}
pub mod repeated_enum {
use alloc::vec::Vec;
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &[crate::EnumValue<E>],
s: S,
) -> Result<S::Ok, S::Error> {
serde::Serialize::serialize(value, s)
}
pub fn deserialize<'de, E: crate::Enumeration, D: Deserializer<'de>>(
d: D,
) -> Result<Vec<crate::EnumValue<E>>, D::Error> {
struct V<E>(core::marker::PhantomData<E>);
impl<'de, E: crate::Enumeration> serde::de::Visitor<'de> for V<E> {
type Value = Vec<crate::EnumValue<E>>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a list of enum values or null")
}
fn visit_unit<Err>(self) -> Result<Vec<crate::EnumValue<E>>, Err> {
Ok(Vec::new())
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(
self,
mut seq: A,
) -> Result<Vec<crate::EnumValue<E>>, A::Error> {
let mut out = Vec::with_capacity(super::clamp_size_hint(seq.size_hint()));
while let Some(raw) = seq.next_element::<serde_json::Value>()? {
match super::try_deserialize_enum::<crate::EnumValue<E>>(raw) {
Ok(Some(v)) => out.push(v),
Ok(None) => continue,
Err(e) => return Err(serde::de::Error::custom(e)),
}
}
Ok(out)
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
pub mod map_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<
K: serde::Serialize + Eq + core::hash::Hash,
E: crate::Enumeration,
S: Serializer,
>(
value: &crate::__private::HashMap<K, crate::EnumValue<E>>,
s: S,
) -> Result<S::Ok, S::Error> {
serde::Serialize::serialize(value, s)
}
pub fn deserialize<
'de,
K: serde::Deserialize<'de> + Eq + core::hash::Hash,
E: crate::Enumeration,
D: Deserializer<'de>,
>(
d: D,
) -> Result<crate::__private::HashMap<K, crate::EnumValue<E>>, D::Error> {
struct V<K, E>(core::marker::PhantomData<(K, E)>);
impl<'de, K: serde::Deserialize<'de> + Eq + core::hash::Hash, E: crate::Enumeration>
serde::de::Visitor<'de> for V<K, E>
{
type Value = crate::__private::HashMap<K, crate::EnumValue<E>>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a map with enum values or null")
}
fn visit_unit<Err>(self) -> Result<Self::Value, Err> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::with_capacity(super::clamp_size_hint(
map.size_hint(),
));
while let Some(key) = map.next_key::<K>()? {
let raw = map.next_value::<serde_json::Value>()?;
match super::try_deserialize_enum::<crate::EnumValue<E>>(raw) {
Ok(Some(v)) => {
out.insert(key, v);
}
Ok(None) => continue,
Err(e) => return Err(serde::de::Error::custom(e)),
}
}
Ok(out)
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
pub fn null_as_default<'de, D, T>(d: D) -> Result<T, D::Error>
where
D: serde::Deserializer<'de>,
T: Default + serde::Deserialize<'de>,
{
<Option<T> as serde::Deserialize>::deserialize(d).map(|opt| opt.unwrap_or_default())
}
fn is_exact_integer(f: f64) -> bool {
f.is_finite() && f == (f as i128 as f64)
}
fn parse_int_from_str<I: TryFrom<i128>>(v: &str) -> Option<I> {
if let Ok(n) = v.parse::<i128>() {
return I::try_from(n).ok();
}
let f: f64 = v.parse().ok()?;
if !is_exact_integer(f) {
return None;
}
I::try_from(f as i128).ok()
}
fn f64_to_int<I: TryFrom<i128>>(v: f64) -> Option<I> {
if !is_exact_integer(v) {
return None;
}
I::try_from(v as i128).ok()
}
macro_rules! int_serde_module {
(
$mod_name:ident, $int_type:ty,
doc = $doc:expr,
serialize_body = |$val:ident, $ser:ident| $ser_body:expr,
expecting = $expecting:expr,
visit_i64_body = $visit_i64:expr,
visit_u64_body = $visit_u64:expr,
visit_str_body = $visit_str:expr $(,)?
) => {
#[doc = $doc]
pub mod $mod_name {
use super::*;
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &$int_type, s: S) -> Result<S::Ok, S::Error> {
let $val = value;
let $ser = s;
$ser_body
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<$int_type, D::Error> {
struct Vis;
impl<'de> serde::de::Visitor<'de> for Vis {
type Value = $int_type;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str($expecting)
}
fn visit_unit<E>(self) -> Result<$int_type, E> {
Ok(0)
}
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<$int_type, E> {
let convert: fn(i64, &dyn serde::de::Expected) -> Result<$int_type, E> =
$visit_i64;
convert(v, &self)
}
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<$int_type, E> {
let convert: fn(u64, &dyn serde::de::Expected) -> Result<$int_type, E> =
$visit_u64;
convert(v, &self)
}
fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<$int_type, E> {
f64_to_int::<$int_type>(v)
.ok_or_else(|| E::invalid_value(serde::de::Unexpected::Float(v), &self))
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<$int_type, E> {
let convert: fn(&str, &dyn serde::de::Expected) -> Result<$int_type, E> =
$visit_str;
convert(v, &self)
}
}
d.deserialize_any(Vis)
}
}
};
}
fn default_visit_str<I: TryFrom<i128>, E: serde::de::Error>(
v: &str,
exp: &dyn serde::de::Expected,
) -> Result<I, E> {
parse_int_from_str::<I>(v).ok_or_else(|| E::invalid_value(serde::de::Unexpected::Str(v), exp))
}
int_serde_module!(
int32,
i32,
doc = "Serde with-module for `i32` fields.\n\n\
Proto JSON accepts integers as numbers, quoted decimal strings, or\n\
float notation (e.g. `1.0`, `1e5`). Serializes as a JSON number.\n\n\
Use with `#[serde(with = \"::buffa::json_helpers::int32\")]`.",
serialize_body = |v, s| s.serialize_i32(*v),
expecting = "an i32 as integer, string, float, or null",
visit_i64_body = |v, exp| {
i32::try_from(v)
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), exp))
},
visit_u64_body = |v, exp| {
i32::try_from(v)
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), exp))
},
visit_str_body = default_visit_str,
);
int_serde_module!(
uint32,
u32,
doc = "Serde with-module for `u32` fields.\n\n\
Proto JSON accepts integers as numbers, quoted decimal strings, or\n\
float notation (e.g. `1.0`, `1e5`). Serializes as a JSON number.\n\n\
Use with `#[serde(with = \"::buffa::json_helpers::uint32\")]`.",
serialize_body = |v, s| s.serialize_u32(*v),
expecting = "a u32 as integer, string, float, or null",
visit_i64_body = |v, exp| {
u32::try_from(v)
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), exp))
},
visit_u64_body = |v, exp| {
u32::try_from(v)
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), exp))
},
visit_str_body = default_visit_str,
);
int_serde_module!(
int64,
i64,
doc = "Serde with-module for `i64` fields encoded as a quoted decimal string.\n\n\
Proto JSON also accepts unquoted integers and float notation.\n\n\
Use with `#[serde(with = \"::buffa::json_helpers::int64\")]`.",
serialize_body = |v, s| s.serialize_str(&v.to_string()),
expecting = "an i64 as a quoted decimal string, integer, float, or null",
visit_i64_body = |v: i64, _exp| Ok(v),
visit_u64_body = |v, _exp| {
i64::try_from(v).map_err(|_| {
serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &"an i64 value")
})
},
visit_str_body = default_visit_str,
);
fn u64_visit_str<E: serde::de::Error>(v: &str, exp: &dyn serde::de::Expected) -> Result<u64, E> {
if let Ok(n) = v.parse::<u64>() {
return Ok(n);
}
parse_int_from_str::<u64>(v).ok_or_else(|| E::invalid_value(serde::de::Unexpected::Str(v), exp))
}
int_serde_module!(
uint64,
u64,
doc = "Serde with-module for `u64` fields encoded as a quoted decimal string.\n\n\
Proto JSON also accepts unquoted integers and float notation.\n\n\
Use with `#[serde(with = \"::buffa::json_helpers::uint64\")]`.",
serialize_body = |v, s| s.serialize_str(&v.to_string()),
expecting = "a u64 as a quoted decimal string, integer, float, or null",
visit_i64_body = |v, _exp| {
u64::try_from(v).map_err(|_| {
serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &"a u64 value")
})
},
visit_u64_body = |v: u64, _exp| Ok(v),
visit_str_body = u64_visit_str,
);
pub mod float {
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &f32, s: S) -> Result<S::Ok, S::Error> {
if value.is_nan() {
s.serialize_str("NaN")
} else if *value == f32::INFINITY {
s.serialize_str("Infinity")
} else if *value == f32::NEG_INFINITY {
s.serialize_str("-Infinity")
} else {
s.serialize_f32(*value)
}
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<f32, D::Error> {
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = f32;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(r#"a float, "NaN", "Infinity", "-Infinity", or null"#)
}
fn visit_unit<E>(self) -> Result<f32, E> {
Ok(0.0)
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<f32, E> {
match v {
"NaN" => Ok(f32::NAN),
"Infinity" => Ok(f32::INFINITY),
"-Infinity" => Ok(f32::NEG_INFINITY),
_ => v.parse::<f32>().map_err(|_| {
E::invalid_value(
serde::de::Unexpected::Str(v),
&r#"a float, or "NaN", "Infinity", "-Infinity""#,
)
}),
}
}
fn visit_f32<E: serde::de::Error>(self, v: f32) -> Result<f32, E> {
Ok(v)
}
fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<f32, E> {
let f = v as f32;
if v.is_finite() && !f.is_finite() {
return Err(E::invalid_value(
serde::de::Unexpected::Float(v),
&"a finite f32 value",
));
}
Ok(f)
}
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<f32, E> {
Ok(v as f32)
}
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<f32, E> {
Ok(v as f32)
}
}
d.deserialize_any(V)
}
}
pub mod double {
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &f64, s: S) -> Result<S::Ok, S::Error> {
if value.is_nan() {
s.serialize_str("NaN")
} else if *value == f64::INFINITY {
s.serialize_str("Infinity")
} else if *value == f64::NEG_INFINITY {
s.serialize_str("-Infinity")
} else {
s.serialize_f64(*value)
}
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<f64, D::Error> {
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = f64;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(r#"a double, "NaN", "Infinity", "-Infinity", or null"#)
}
fn visit_unit<E>(self) -> Result<f64, E> {
Ok(0.0)
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<f64, E> {
match v {
"NaN" => Ok(f64::NAN),
"Infinity" => Ok(f64::INFINITY),
"-Infinity" => Ok(f64::NEG_INFINITY),
_ => v.parse::<f64>().map_err(|_| {
E::invalid_value(
serde::de::Unexpected::Str(v),
&r#"a double, or "NaN", "Infinity", "-Infinity""#,
)
}),
}
}
fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<f64, E> {
Ok(v)
}
fn visit_f32<E: serde::de::Error>(self, v: f32) -> Result<f64, E> {
Ok(v as f64)
}
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<f64, E> {
Ok(v as f64)
}
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<f64, E> {
Ok(v as f64)
}
}
d.deserialize_any(V)
}
}
pub mod bytes {
use super::STANDARD;
use base64::Engine as _;
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &[u8], s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(&STANDARD.encode(value))
}
pub fn deserialize<'de, T, D>(d: D) -> Result<T, D::Error>
where
T: From<alloc::vec::Vec<u8>>,
D: Deserializer<'de>,
{
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = alloc::vec::Vec<u8>;
fn visit_unit<E>(self) -> Result<alloc::vec::Vec<u8>, E> {
Ok(alloc::vec::Vec::new())
}
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a base64-encoded string, or null")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<alloc::vec::Vec<u8>, E> {
super::decode_base64(v).map_err(serde::de::Error::custom)
}
}
d.deserialize_any(V).map(T::from)
}
}
proto_elem_json_delegate!(i32, int32);
proto_elem_json_delegate!(u32, uint32);
proto_elem_json_delegate!(i64, int64);
proto_elem_json_delegate!(u64, uint64);
proto_elem_json_delegate!(f32, float);
proto_elem_json_delegate!(f64, double);
proto_elem_json_delegate!(bool, proto_bool);
proto_elem_json_delegate!(alloc::string::String, proto_string);
proto_elem_json_delegate!(alloc::vec::Vec<u8>, bytes);
impl ProtoElemJson for ::bytes::Bytes {
fn serialize_proto_json<S: serde::Serializer>(v: &Self, s: S) -> Result<S::Ok, S::Error> {
bytes::serialize(v, s)
}
fn deserialize_proto_json<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
bytes::deserialize(d)
}
}
impl<E: crate::Enumeration> ProtoElemJson for crate::EnumValue<E>
where
Self: serde::Serialize + serde::de::DeserializeOwned,
{
fn serialize_proto_json<S: serde::Serializer>(v: &Self, s: S) -> Result<S::Ok, S::Error> {
serde::Serialize::serialize(v, s)
}
fn deserialize_proto_json<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
<Self as serde::Deserialize>::deserialize(d)
}
}
pub mod bytes_key_map {
use serde::{Deserializer, Serializer};
pub fn serialize<V, S>(
value: &crate::__private::HashMap<alloc::vec::Vec<u8>, V>,
s: S,
) -> Result<S::Ok, S::Error>
where
V: serde::Serialize,
S: Serializer,
{
use serde::ser::SerializeMap;
let mut map = s.serialize_map(Some(value.len()))?;
for (k, v) in value {
map.serialize_entry(&super::Base64Wrapper(k), v)?;
}
map.end()
}
pub fn deserialize<'de, V, D>(
d: D,
) -> Result<crate::__private::HashMap<alloc::vec::Vec<u8>, V>, D::Error>
where
V: serde::Deserialize<'de>,
D: Deserializer<'de>,
{
struct Vis<V>(core::marker::PhantomData<V>);
impl<'de, V: serde::Deserialize<'de>> serde::de::Visitor<'de> for Vis<V> {
type Value = crate::__private::HashMap<alloc::vec::Vec<u8>, V>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a map with base64-encoded keys, or null")
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::new();
while let Some(key_str) = map.next_key::<alloc::string::String>()? {
let k = super::decode_base64(&key_str).map_err(serde::de::Error::custom)?;
let v: V = map.next_value()?;
out.insert(k, v);
}
Ok(out)
}
}
d.deserialize_any(Vis(core::marker::PhantomData))
}
}
pub mod bytes_key_bytes_val_map {
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(
value: &crate::__private::HashMap<alloc::vec::Vec<u8>, alloc::vec::Vec<u8>>,
s: S,
) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let mut map = s.serialize_map(Some(value.len()))?;
for (k, v) in value {
map.serialize_entry(&super::Base64Wrapper(k), &super::Base64Wrapper(v))?;
}
map.end()
}
pub fn deserialize<'de, D: Deserializer<'de>>(
d: D,
) -> Result<crate::__private::HashMap<alloc::vec::Vec<u8>, alloc::vec::Vec<u8>>, D::Error> {
struct V;
impl<'de> serde::de::Visitor<'de> for V {
type Value = crate::__private::HashMap<alloc::vec::Vec<u8>, alloc::vec::Vec<u8>>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a map with base64-encoded keys and values, or null")
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::new();
while let Some((ks, vs)) =
map.next_entry::<alloc::string::String, alloc::string::String>()?
{
let k = super::decode_base64(&ks).map_err(serde::de::Error::custom)?;
let v = super::decode_base64(&vs).map_err(serde::de::Error::custom)?;
out.insert(k, v);
}
Ok(out)
}
}
d.deserialize_any(V)
}
}
pub mod string_key_map {
use alloc::string::ToString;
use core::fmt::Display;
use core::hash::Hash;
use core::str::FromStr;
use serde::{Deserializer, Serializer};
pub fn serialize<K, V, S>(
value: &crate::__private::HashMap<K, V>,
s: S,
) -> Result<S::Ok, S::Error>
where
K: Display + Eq + Hash,
V: serde::Serialize,
S: Serializer,
{
use serde::ser::SerializeMap;
let mut map = s.serialize_map(Some(value.len()))?;
for (k, v) in value {
map.serialize_entry(&k.to_string(), v)?;
}
map.end()
}
pub fn deserialize<'de, K, V, D>(d: D) -> Result<crate::__private::HashMap<K, V>, D::Error>
where
K: FromStr + Eq + Hash,
K::Err: Display,
V: serde::Deserialize<'de>,
D: Deserializer<'de>,
{
struct MapVisitor<K, V>(core::marker::PhantomData<(K, V)>);
impl<'de, K, V> serde::de::Visitor<'de> for MapVisitor<K, V>
where
K: FromStr + Eq + Hash,
K::Err: Display,
V: serde::Deserialize<'de>,
{
type Value = crate::__private::HashMap<K, V>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a JSON object with string keys, or null")
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::new();
while let Some(key_str) = map.next_key::<alloc::string::String>()? {
let key = key_str.parse::<K>().map_err(|e| {
serde::de::Error::custom(alloc::format!(
"invalid map key '{}': {}",
key_str,
e
))
})?;
let value = map.next_value()?;
out.insert(key, value);
}
Ok(out)
}
}
d.deserialize_any(MapVisitor(core::marker::PhantomData))
}
}
struct Base64Wrapper<'a>(&'a [u8]);
impl serde::Serialize for Base64Wrapper<'_> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
bytes::serialize(self.0, s)
}
}
fn decode_base64(v: &str) -> Result<alloc::vec::Vec<u8>, base64::DecodeError> {
use base64::Engine as _;
STANDARD_LENIENT
.decode(v)
.or_else(|std_err| URL_SAFE_LENIENT.decode(v).map_err(|_| std_err))
}
macro_rules! opt_serde_module {
($mod_name:ident, $inner:ident, $ty:ty) => {
pub mod $mod_name {
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(value: &Option<$ty>, s: S) -> Result<S::Ok, S::Error> {
match value {
Some(v) => super::$inner::serialize(v, s),
None => s.serialize_none(),
}
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<$ty>, D::Error> {
<Option<super::$mod_name::Helper> as serde::Deserialize>::deserialize(d)
.map(|opt| opt.map(|h| h.0))
}
struct Helper($ty);
impl<'de> serde::Deserialize<'de> for Helper {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
super::$inner::deserialize(d).map(Helper)
}
}
}
};
}
opt_serde_module!(opt_int32, int32, i32);
opt_serde_module!(opt_uint32, uint32, u32);
opt_serde_module!(opt_int64, int64, i64);
opt_serde_module!(opt_uint64, uint64, u64);
opt_serde_module!(opt_float, float, f32);
opt_serde_module!(opt_double, double, f64);
pub mod opt_bytes {
use serde::{Deserializer, Serializer};
pub fn serialize<T, S>(value: &Option<T>, s: S) -> Result<S::Ok, S::Error>
where
T: AsRef<[u8]>,
S: Serializer,
{
match value {
Some(v) => super::bytes::serialize(v.as_ref(), s),
None => s.serialize_none(),
}
}
pub fn deserialize<'de, T, D>(d: D) -> Result<Option<T>, D::Error>
where
T: From<alloc::vec::Vec<u8>>,
D: Deserializer<'de>,
{
struct Helper(alloc::vec::Vec<u8>);
impl<'de> serde::Deserialize<'de> for Helper {
fn deserialize<D2: Deserializer<'de>>(d: D2) -> Result<Self, D2::Error> {
super::bytes::deserialize::<alloc::vec::Vec<u8>, _>(d).map(Helper)
}
}
<Option<Helper> as serde::Deserialize>::deserialize(d).map(|opt| opt.map(|h| h.0.into()))
}
}
pub mod opt_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &Option<crate::EnumValue<E>>,
s: S,
) -> Result<S::Ok, S::Error> {
match value {
Some(v) => serde::Serialize::serialize(v, s),
None => s.serialize_none(),
}
}
pub fn deserialize<'de, E: crate::Enumeration, D: Deserializer<'de>>(
d: D,
) -> Result<Option<crate::EnumValue<E>>, D::Error> {
let raw: Option<serde_json::Value> = serde::Deserialize::deserialize(d)?;
let raw = match raw {
Some(v) => v,
None => return Ok(None),
};
super::try_deserialize_enum::<crate::EnumValue<E>>(raw).map_err(serde::de::Error::custom)
}
}
pub struct NullableDeserializeSeed<S>(pub S);
impl<'de, S> serde::de::DeserializeSeed<'de> for NullableDeserializeSeed<S>
where
S: serde::de::DeserializeSeed<'de>,
{
type Value = Option<S::Value>;
fn deserialize<D: serde::Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
d.deserialize_option(NullableVisitor(self.0))
}
}
struct NullableVisitor<S>(S);
impl<'de, S> serde::de::Visitor<'de> for NullableVisitor<S>
where
S: serde::de::DeserializeSeed<'de>,
{
type Value = Option<S::Value>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a value or null")
}
fn visit_none<E>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_some<D: serde::Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
self.0.deserialize(d).map(Some)
}
}
pub struct DefaultDeserializeSeed<T>(core::marker::PhantomData<T>);
impl<T> DefaultDeserializeSeed<T> {
pub fn new() -> Self {
Self(core::marker::PhantomData)
}
}
impl<T> Default for DefaultDeserializeSeed<T> {
fn default() -> Self {
Self::new()
}
}
impl<'de, T: serde::Deserialize<'de>> serde::de::DeserializeSeed<'de>
for DefaultDeserializeSeed<T>
{
type Value = T;
fn deserialize<D: serde::Deserializer<'de>>(self, d: D) -> Result<T, D::Error> {
T::deserialize(d)
}
}
pub fn message_field_always_present<'de, T, D>(d: D) -> Result<crate::MessageField<T>, D::Error>
where
T: Default + serde::Deserialize<'de>,
D: serde::Deserializer<'de>,
{
T::deserialize(d).map(crate::MessageField::some)
}
pub(crate) struct EnumProtoNameRef<'a, E: crate::Enumeration>(pub &'a E);
impl<E: crate::Enumeration> serde::Serialize for EnumProtoNameRef<'_, E> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(self.0.proto_name())
}
}
pub mod skip_if {
pub fn is_zero_i32(v: &i32) -> bool {
*v == 0
}
pub fn is_zero_i64(v: &i64) -> bool {
*v == 0
}
pub fn is_zero_u32(v: &u32) -> bool {
*v == 0
}
pub fn is_zero_u64(v: &u64) -> bool {
*v == 0
}
pub fn is_false(v: &bool) -> bool {
!*v
}
pub fn is_zero_f32(v: &f32) -> bool {
*v == 0.0
}
pub fn is_zero_f64(v: &f64) -> bool {
*v == 0.0
}
pub fn is_empty_str(v: &str) -> bool {
v.is_empty()
}
pub fn is_empty_bytes(v: &[u8]) -> bool {
v.is_empty()
}
pub fn is_empty_vec<T>(v: &[T]) -> bool {
v.is_empty()
}
pub fn is_unset_message_field<T: Default>(v: &crate::MessageField<T>) -> bool {
v.is_unset()
}
pub fn is_default_enum_value<E: crate::Enumeration>(v: &crate::EnumValue<E>) -> bool {
v.to_i32() == 0
}
pub fn is_default_closed_enum<E: crate::Enumeration>(v: &E) -> bool {
v.to_i32() == 0
}
}
pub mod closed_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &E,
s: S,
) -> Result<S::Ok, S::Error> {
s.serialize_str(value.proto_name())
}
pub fn deserialize<'de, E: crate::Enumeration + Default, D: Deserializer<'de>>(
d: D,
) -> Result<E, D::Error> {
struct V<E>(core::marker::PhantomData<E>);
impl<'de, E: crate::Enumeration + Default> serde::de::Visitor<'de> for V<E> {
type Value = E;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a protobuf enum name string, integer value, or null")
}
fn visit_unit<Err>(self) -> Result<E, Err> {
Ok(E::default())
}
fn visit_i64<Err: serde::de::Error>(self, v: i64) -> Result<E, Err> {
let v32 = i32::try_from(v).map_err(|_| {
serde::de::Error::custom(alloc::format!("enum value {} out of i32 range", v))
})?;
E::from_i32(v32).ok_or_else(|| {
serde::de::Error::custom(alloc::format!("unknown enum value {}", v32))
})
}
fn visit_u64<Err: serde::de::Error>(self, v: u64) -> Result<E, Err> {
let v32 = i32::try_from(v).map_err(|_| {
serde::de::Error::custom(alloc::format!("enum value {} out of i32 range", v))
})?;
E::from_i32(v32).ok_or_else(|| {
serde::de::Error::custom(alloc::format!("unknown enum value {}", v32))
})
}
fn visit_str<Err: serde::de::Error>(self, v: &str) -> Result<E, Err> {
match E::from_proto_name(v) {
Some(e) => Ok(e),
None => {
if crate::json::ignore_unknown_enum_values() {
return Ok(E::default());
}
Err(serde::de::Error::unknown_variant(v, &[]))
}
}
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
pub mod opt_closed_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &Option<E>,
s: S,
) -> Result<S::Ok, S::Error> {
match value {
Some(v) => s.serialize_str(v.proto_name()),
None => s.serialize_none(),
}
}
pub fn deserialize<
'de,
E: crate::Enumeration + Default + serde::de::DeserializeOwned,
D: Deserializer<'de>,
>(
d: D,
) -> Result<Option<E>, D::Error> {
let raw: Option<serde_json::Value> = serde::Deserialize::deserialize(d)?;
let raw = match raw {
Some(v) => v,
None => return Ok(None),
};
super::try_deserialize_enum::<E>(raw).map_err(serde::de::Error::custom)
}
}
pub mod repeated_closed_enum {
use alloc::vec::Vec;
use serde::{Deserializer, Serializer};
pub fn serialize<E: crate::Enumeration, S: Serializer>(
value: &[E],
s: S,
) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let mut seq = s.serialize_seq(Some(value.len()))?;
for v in value {
seq.serialize_element(&crate::json_helpers::EnumProtoNameRef(v))?;
}
seq.end()
}
pub fn deserialize<
'de,
E: crate::Enumeration + Default + serde::de::DeserializeOwned,
D: Deserializer<'de>,
>(
d: D,
) -> Result<Vec<E>, D::Error> {
struct V<E>(core::marker::PhantomData<E>);
impl<'de, E: crate::Enumeration + Default + serde::de::DeserializeOwned>
serde::de::Visitor<'de> for V<E>
{
type Value = Vec<E>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a list of enum values or null")
}
fn visit_unit<Err>(self) -> Result<Vec<E>, Err> {
Ok(Vec::new())
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(
self,
mut seq: A,
) -> Result<Vec<E>, A::Error> {
let mut out = Vec::with_capacity(super::clamp_size_hint(seq.size_hint()));
while let Some(raw) = seq.next_element::<serde_json::Value>()? {
match super::try_deserialize_enum::<E>(raw) {
Ok(Some(v)) => out.push(v),
Ok(None) => continue,
Err(e) => return Err(serde::de::Error::custom(e)),
}
}
Ok(out)
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
pub mod map_closed_enum {
use serde::{Deserializer, Serializer};
pub fn serialize<
K: serde::Serialize + Eq + core::hash::Hash,
E: crate::Enumeration,
S: Serializer,
>(
value: &crate::__private::HashMap<K, E>,
s: S,
) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let mut map = s.serialize_map(Some(value.len()))?;
for (k, v) in value {
map.serialize_entry(k, &crate::json_helpers::EnumProtoNameRef(v))?;
}
map.end()
}
pub fn deserialize<
'de,
K: serde::Deserialize<'de> + Eq + core::hash::Hash,
E: crate::Enumeration + Default + serde::de::DeserializeOwned,
D: Deserializer<'de>,
>(
d: D,
) -> Result<crate::__private::HashMap<K, E>, D::Error> {
struct V<K, E>(core::marker::PhantomData<(K, E)>);
impl<
'de,
K: serde::Deserialize<'de> + Eq + core::hash::Hash,
E: crate::Enumeration + Default + serde::de::DeserializeOwned,
> serde::de::Visitor<'de> for V<K, E>
{
type Value = crate::__private::HashMap<K, E>;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("a map with enum values or null")
}
fn visit_unit<Err>(self) -> Result<Self::Value, Err> {
Ok(crate::__private::HashMap::new())
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut out = crate::__private::HashMap::with_capacity(super::clamp_size_hint(
map.size_hint(),
));
while let Some(key) = map.next_key::<K>()? {
let raw = map.next_value::<serde_json::Value>()?;
match super::try_deserialize_enum::<E>(raw) {
Ok(Some(v)) => {
out.insert(key, v);
}
Ok(None) => continue,
Err(e) => return Err(serde::de::Error::custom(e)),
}
}
Ok(out)
}
}
d.deserialize_any(V(core::marker::PhantomData))
}
}
#[cfg(test)]
mod tests;