use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use crate::{
MultiValues,
Value,
ValueContainer,
};
#[cfg(feature = "json")]
use crate::{
ValueWireDecodeError,
WireLimits,
};
use super::value_wire_payload_ref_v1::{
validate_value,
validate_values,
};
use super::{
ValueWireEncodeError,
WireShapeOwned,
WireShapeRef,
};
#[must_use]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ValueWirePayloadV1 {
value: ValueContainer,
}
impl ValueWirePayloadV1 {
#[cfg(feature = "json")]
#[inline]
pub fn decode_json_slice(
input: &[u8],
) -> Result<Self, ValueWireDecodeError> {
Self::decode_json_slice_with_limits(input, WireLimits::default())
}
#[cfg(feature = "json")]
#[inline]
pub fn decode_json_slice_with_limits(
input: &[u8],
limits: WireLimits,
) -> Result<Self, ValueWireDecodeError> {
let mut budget = limits.begin(input.len())?;
let value: Self = serde_json::from_slice(input)
.map_err(ValueWireDecodeError::from)?;
budget.check_container(value.container())?;
Ok(value)
}
#[inline(always)]
pub const fn container(&self) -> &ValueContainer {
&self.value
}
#[inline(always)]
pub fn into_container(self) -> ValueContainer {
self.value
}
fn try_new(value: ValueContainer) -> Result<Self, ValueWireEncodeError> {
match &value {
ValueContainer::Scalar(value) => validate_value(value)?,
ValueContainer::Collection(values) => validate_values(values)?,
}
Ok(Self { value })
}
pub(in crate::value_wire) const fn from_decoded(
value: ValueContainer,
) -> Self {
Self { value }
}
}
impl TryFrom<Value> for ValueWirePayloadV1 {
type Error = ValueWireEncodeError;
#[inline(always)]
fn try_from(value: Value) -> Result<Self, Self::Error> {
Self::try_new(value.into())
}
}
impl TryFrom<MultiValues> for ValueWirePayloadV1 {
type Error = ValueWireEncodeError;
#[inline(always)]
fn try_from(value: MultiValues) -> Result<Self, Self::Error> {
Self::try_new(value.into())
}
}
impl TryFrom<ValueContainer> for ValueWirePayloadV1 {
type Error = ValueWireEncodeError;
#[inline(always)]
fn try_from(value: ValueContainer) -> Result<Self, Self::Error> {
Self::try_new(value)
}
}
impl From<ValueWirePayloadV1> for ValueContainer {
#[inline(always)]
fn from(value: ValueWirePayloadV1) -> Self {
value.into_container()
}
}
impl Serialize for ValueWirePayloadV1 {
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
WireShapeRef::from(&self.value).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ValueWirePayloadV1 {
#[inline(always)]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self::from_decoded(
WireShapeOwned::deserialize(deserializer)?.into(),
))
}
}