#[cfg(feature = "json")]
pub(crate) const JSON_NUMBER_TOKEN: &str = "$serde_json::private::Number";
#[cfg(any(feature = "chrono", feature = "url"))]
use serde::Deserialize;
pub(crate) use crate::finite_float::{
float32,
float32_vec,
float64,
float64_vec,
};
pub(crate) use crate::wide_integer::{
int128,
int128_vec,
uint128,
uint128_vec,
};
pub(crate) mod string_map;
pub(crate) mod string_map_vec;
#[cfg(feature = "json")]
pub(crate) mod json;
#[cfg(feature = "json")]
pub(crate) mod json_vec;
#[cfg(feature = "big-integer")]
mod decimal;
mod internal;
#[cfg(feature = "big-decimal")]
use internal::BigDecimalPayload;
use internal::DurationPayload;
#[cfg(feature = "big-decimal")]
pub(crate) const MAX_BIG_DECIMAL_ABSOLUTE_SCALE: i64 = 150_000;
#[cfg(feature = "big-decimal")]
#[inline(always)]
pub(crate) const fn is_valid_big_decimal_scale(scale: i64) -> bool {
scale.unsigned_abs() <= MAX_BIG_DECIMAL_ABSOLUTE_SCALE as u64
}
#[cfg(any(feature = "chrono", feature = "url"))]
fn serialize_canonical<S, T, F>(
value: &T,
serializer: S,
format: F,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
F: FnOnce(&T) -> String,
{
serializer.serialize_str(&format(value))
}
#[cfg(any(feature = "chrono", feature = "url"))]
fn deserialize_canonical<'de, D, T, P, F>(
deserializer: D,
parse: P,
format: F,
) -> Result<T, D::Error>
where
D: serde::Deserializer<'de>,
P: FnOnce(&str) -> Result<T, String>,
F: FnOnce(&T) -> String,
{
use serde::de::Error as _;
let input = String::deserialize(deserializer)?;
let value = parse(&input).map_err(D::Error::custom)?;
if format(&value) != input {
return Err(D::Error::custom("non-canonical V1 string payload"));
}
Ok(value)
}
#[cfg(any(feature = "chrono", feature = "url"))]
fn serialize_canonical_vec<S, T, F>(
values: &[T],
serializer: S,
format: F,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
F: Fn(&T) -> String,
{
serializer.collect_seq(values.iter().map(format))
}
#[cfg(any(feature = "chrono", feature = "url"))]
fn deserialize_canonical_vec<'de, D, T, P, F>(
deserializer: D,
parse: P,
format: F,
) -> Result<Vec<T>, D::Error>
where
D: serde::Deserializer<'de>,
P: Fn(&str) -> Result<T, String>,
F: Fn(&T) -> String,
{
use serde::de::Error as _;
Vec::<String>::deserialize(deserializer)?
.into_iter()
.map(|input| {
let value = parse(&input).map_err(D::Error::custom)?;
if format(&value) != input {
return Err(D::Error::custom(
"non-canonical V1 string payload",
));
}
Ok(value)
})
.collect()
}
#[cfg(feature = "chrono")]
macro_rules! define_chrono_wire {
($scalar:ident, $vector:ident, $type:ty, $parse:expr, $format:expr) => {
pub(crate) mod $scalar {
use serde::{
Deserializer,
Serializer,
};
pub(crate) fn serialize<S>(
value: &$type,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
super::serialize_canonical(value, serializer, $format)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<$type, D::Error>
where
D: Deserializer<'de>,
{
super::deserialize_canonical(deserializer, $parse, $format)
}
}
pub(crate) mod $vector {
use serde::{
Deserializer,
Serializer,
};
pub(crate) fn serialize<S>(
values: &[$type],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
super::serialize_canonical_vec(values, serializer, $format)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<$type>, D::Error>
where
D: Deserializer<'de>,
{
super::deserialize_canonical_vec(deserializer, $parse, $format)
}
}
};
}
#[cfg(feature = "chrono")]
define_chrono_wire!(
date,
date_vec,
chrono::NaiveDate,
|input| chrono::NaiveDate::parse_from_str(input, "%F")
.map_err(|error| error.to_string()),
|value: &chrono::NaiveDate| value.format("%F").to_string()
);
#[cfg(feature = "chrono")]
define_chrono_wire!(
time,
time_vec,
chrono::NaiveTime,
|input| chrono::NaiveTime::parse_from_str(input, "%H:%M:%S%.f")
.map_err(|error| error.to_string()),
|value: &chrono::NaiveTime| value.format("%H:%M:%S%.f").to_string()
);
#[cfg(feature = "chrono")]
define_chrono_wire!(
datetime,
datetime_vec,
chrono::NaiveDateTime,
|input| chrono::NaiveDateTime::parse_from_str(
input,
"%Y-%m-%dT%H:%M:%S%.f"
)
.map_err(|error| error.to_string()),
|value: &chrono::NaiveDateTime| value
.format("%Y-%m-%dT%H:%M:%S%.f")
.to_string()
);
#[cfg(feature = "chrono")]
define_chrono_wire!(
instant,
instant_vec,
chrono::DateTime<chrono::Utc>,
|input| chrono::DateTime::parse_from_rfc3339(input)
.map(|value| value.with_timezone(&chrono::Utc))
.map_err(|error| error.to_string()),
|value: &chrono::DateTime<chrono::Utc>| value
.to_rfc3339_opts(chrono::SecondsFormat::AutoSi, true)
);
#[cfg(feature = "url")]
macro_rules! define_url_wire {
() => {
pub(crate) mod url {
use serde::{
Deserializer,
Serializer,
};
pub(crate) fn serialize<S>(
value: &::url::Url,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
super::serialize_canonical(
value,
serializer,
|value: &::url::Url| value.as_str().to_owned(),
)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<::url::Url, D::Error>
where
D: Deserializer<'de>,
{
super::deserialize_canonical(
deserializer,
|input| {
::url::Url::parse(input)
.map_err(|error| error.to_string())
},
|value: &::url::Url| value.as_str().to_owned(),
)
}
}
pub(crate) mod url_vec {
use serde::{
Deserializer,
Serializer,
};
pub(crate) fn serialize<S>(
values: &[::url::Url],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
super::serialize_canonical_vec(
values,
serializer,
|value: &::url::Url| value.as_str().to_owned(),
)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<::url::Url>, D::Error>
where
D: Deserializer<'de>,
{
super::deserialize_canonical_vec(
deserializer,
|input| {
::url::Url::parse(input)
.map_err(|error| error.to_string())
},
|value: &::url::Url| value.as_str().to_owned(),
)
}
}
};
}
#[cfg(feature = "url")]
define_url_wire!();
#[cfg(feature = "big-integer")]
macro_rules! define_decimal_serde {
($scalar_module:ident, $vector_module:ident, $type:ty) => {
pub(crate) mod $scalar_module {
use serde::{
Deserializer,
Serializer,
};
use super::decimal;
pub(crate) fn serialize<S>(
value: &$type,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
decimal::serialize(value, serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<$type, D::Error>
where
D: Deserializer<'de>,
{
decimal::deserialize(deserializer)
}
}
pub(crate) mod $vector_module {
use serde::{
Deserializer,
Serializer,
};
use super::decimal;
pub(crate) fn serialize<S>(
values: &[$type],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
decimal::serialize_vec(values, serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<$type>, D::Error>
where
D: Deserializer<'de>,
{
decimal::deserialize_vec(deserializer)
}
}
};
}
#[cfg(feature = "big-integer")]
define_decimal_serde!(big_integer, big_integer_vec, num_bigint::BigInt);
#[cfg(feature = "big-decimal")]
pub(crate) mod big_decimal {
use bigdecimal::BigDecimal;
use serde::de::Error as _;
use serde::ser::Error as _;
use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use super::BigDecimalPayload;
pub(crate) fn serialize<S>(
value: &BigDecimal,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
BigDecimalPayload::try_from(value)
.map_err(S::Error::custom)?
.serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<BigDecimal, D::Error>
where
D: Deserializer<'de>,
{
BigDecimalPayload::deserialize(deserializer)?
.try_into()
.map_err(D::Error::custom)
}
}
#[cfg(feature = "big-decimal")]
pub(crate) mod big_decimal_vec {
use bigdecimal::BigDecimal;
use serde::de::Error as _;
use serde::ser::{
Error as _,
SerializeSeq,
};
use serde::{
Deserialize,
Deserializer,
Serializer,
};
use super::BigDecimalPayload;
pub(crate) fn serialize<S>(
values: &[BigDecimal],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut sequence = serializer.serialize_seq(Some(values.len()))?;
for value in values {
let payload =
BigDecimalPayload::try_from(value).map_err(S::Error::custom)?;
sequence.serialize_element(&payload)?;
}
sequence.end()
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<BigDecimal>, D::Error>
where
D: Deserializer<'de>,
{
Vec::<BigDecimalPayload>::deserialize(deserializer)?
.into_iter()
.map(|value| value.try_into().map_err(D::Error::custom))
.collect()
}
}
pub(crate) mod duration {
use std::time::Duration;
use serde::de::Error as _;
use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use super::DurationPayload;
pub(crate) fn serialize<S>(
value: &Duration,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
DurationPayload::from(value).serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
{
DurationPayload::deserialize(deserializer)?
.try_into()
.map_err(D::Error::custom)
}
}
pub(crate) mod duration_vec {
use std::time::Duration;
use serde::de::Error as _;
use serde::{
Deserialize,
Deserializer,
Serializer,
};
use super::DurationPayload;
pub(crate) fn serialize<S>(
values: &[Duration],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(values.iter().map(DurationPayload::from))
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<Duration>, D::Error>
where
D: Deserializer<'de>,
{
Vec::<DurationPayload>::deserialize(deserializer)?
.into_iter()
.map(|value| value.try_into().map_err(D::Error::custom))
.collect()
}
}