use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use crate::ValueWireRefV1;
#[cfg(feature = "json")]
use crate::{
ValueWireDecodeError,
WireLimits,
};
use super::value::Value;
mod internal;
use internal::{
NamedValueWireOwned,
NamedValueWireRef,
};
#[must_use]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NamedValue {
name: String,
value: Value,
}
impl NamedValue {
#[inline]
pub fn new(name: impl Into<String>, value: Value) -> Self {
Self {
name: name.into(),
value,
}
}
#[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")]
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_named_value(&value)?;
Ok(value)
}
#[inline(always)]
#[must_use = "the borrowed name should be used"]
pub fn name(&self) -> &str {
&self.name
}
#[inline(always)]
pub fn set_name(&mut self, name: impl Into<String>) {
self.name = name.into();
}
#[inline(always)]
#[must_use = "the borrowed value should be used"]
pub fn value(&self) -> &Value {
&self.value
}
#[inline(always)]
#[must_use = "the mutable value reference should be used"]
pub fn value_mut(&mut self) -> &mut Value {
&mut self.value
}
#[inline(always)]
pub fn set_value(&mut self, value: Value) {
self.value = value;
}
#[inline(always)]
#[must_use = "consuming NamedValue without using its parts loses both fields"]
pub fn into_parts(self) -> (String, Value) {
(self.name, self.value)
}
}
impl Serialize for NamedValue {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let value = ValueWireRefV1::try_from(self.value())
.map_err(serde::ser::Error::custom)?;
NamedValueWireRef {
name: self.name(),
value,
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for NamedValue {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let NamedValueWireOwned { name, value } =
NamedValueWireOwned::deserialize(deserializer)?;
let value = value.into_container().into_scalar().map_err(|_| {
serde::de::Error::custom(
"named value wire payload must contain a scalar",
)
})?;
Ok(Self::new(name, value))
}
}