mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-24 15:55:49 +00:00
Implement Serialize/Deserialize on WeakBoundedVec (#11713)
* Implement Serialize/Deserialize on WeakBoundedVec * cargo fmt * Warn when there are too many elements while deserializing WeakBoundedVec
This commit is contained in:
@@ -25,6 +25,11 @@ use core::{
|
|||||||
ops::{Deref, Index, IndexMut},
|
ops::{Deref, Index, IndexMut},
|
||||||
slice::SliceIndex,
|
slice::SliceIndex,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use serde::{
|
||||||
|
de::{Error, SeqAccess, Visitor},
|
||||||
|
Deserialize, Deserializer, Serialize,
|
||||||
|
};
|
||||||
use sp_std::{marker::PhantomData, prelude::*};
|
use sp_std::{marker::PhantomData, prelude::*};
|
||||||
|
|
||||||
/// A weakly bounded vector.
|
/// A weakly bounded vector.
|
||||||
@@ -34,9 +39,72 @@ use sp_std::{marker::PhantomData, prelude::*};
|
|||||||
///
|
///
|
||||||
/// The length of the vec is not strictly bounded. Decoding a vec with more element that the bound
|
/// The length of the vec is not strictly bounded. Decoding a vec with more element that the bound
|
||||||
/// is accepted, and some method allow to bypass the restriction with warnings.
|
/// is accepted, and some method allow to bypass the restriction with warnings.
|
||||||
|
#[cfg_attr(feature = "std", derive(Serialize), serde(transparent))]
|
||||||
#[derive(Encode, scale_info::TypeInfo)]
|
#[derive(Encode, scale_info::TypeInfo)]
|
||||||
#[scale_info(skip_type_params(S))]
|
#[scale_info(skip_type_params(S))]
|
||||||
pub struct WeakBoundedVec<T, S>(pub(super) Vec<T>, PhantomData<S>);
|
pub struct WeakBoundedVec<T, S>(
|
||||||
|
pub(super) Vec<T>,
|
||||||
|
#[cfg_attr(feature = "std", serde(skip_serializing))] PhantomData<S>,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<'de, T, S: Get<u32>> Deserialize<'de> for WeakBoundedVec<T, S>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct VecVisitor<T, S: Get<u32>>(PhantomData<(T, S)>);
|
||||||
|
|
||||||
|
impl<'de, T, S: Get<u32>> Visitor<'de> for VecVisitor<T, S>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = Vec<T>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("a sequence")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let size = seq.size_hint().unwrap_or(0);
|
||||||
|
let max = match usize::try_from(S::get()) {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => return Err(A::Error::custom("can't convert to usize")),
|
||||||
|
};
|
||||||
|
if size > max {
|
||||||
|
log::warn!(
|
||||||
|
target: "runtime",
|
||||||
|
"length of a bounded vector while deserializing is not respected.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut values = Vec::with_capacity(size);
|
||||||
|
|
||||||
|
while let Some(value) = seq.next_element()? {
|
||||||
|
values.push(value);
|
||||||
|
if values.len() > max {
|
||||||
|
log::warn!(
|
||||||
|
target: "runtime",
|
||||||
|
"length of a bounded vector while deserializing is not respected.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let visitor: VecVisitor<T, S> = VecVisitor(PhantomData);
|
||||||
|
deserializer.deserialize_seq(visitor).map(|v| {
|
||||||
|
WeakBoundedVec::<T, S>::try_from(v).map_err(|_| Error::custom("out of bounds"))
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Decode, S: Get<u32>> Decode for WeakBoundedVec<T, S> {
|
impl<T: Decode, S: Get<u32>> Decode for WeakBoundedVec<T, S> {
|
||||||
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
|
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
|
||||||
|
|||||||
Reference in New Issue
Block a user