mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 06:57:58 +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},
|
||||
slice::SliceIndex,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{
|
||||
de::{Error, SeqAccess, Visitor},
|
||||
Deserialize, Deserializer, Serialize,
|
||||
};
|
||||
use sp_std::{marker::PhantomData, prelude::*};
|
||||
|
||||
/// 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
|
||||
/// 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)]
|
||||
#[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> {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
|
||||
|
||||
Reference in New Issue
Block a user