referrerpolicy=no-referrer-when-downgrade

snowbridge_beacon_primitives/
serde_utils.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
3use sp_core::U256;
4
5use core::fmt::Formatter;
6use serde::{Deserialize, Deserializer};
7
8// helper to deserialize arbitrary arrays like [T; N]
9pub mod arrays {
10	use std::marker::PhantomData;
11
12	use serde::{
13		de::{SeqAccess, Visitor},
14		ser::SerializeTuple,
15		Deserialize, Deserializer, Serialize, Serializer,
16	};
17
18	pub fn serialize<S: Serializer, T: Serialize, const N: usize>(
19		data: &[T; N],
20		ser: S,
21	) -> Result<S::Ok, S::Error> {
22		let mut s = ser.serialize_tuple(N)?;
23		for item in data {
24			s.serialize_element(item)?;
25		}
26		s.end()
27	}
28
29	struct ArrayVisitor<T, const N: usize>(PhantomData<T>);
30
31	impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<T, N>
32	where
33		T: Deserialize<'de>,
34	{
35		type Value = [T; N];
36
37		fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
38			formatter.write_str(&format!("an array of length {}", N))
39		}
40
41		#[inline]
42		fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
43		where
44			A: SeqAccess<'de>,
45		{
46			// can be optimized using MaybeUninit
47			let mut data = Vec::with_capacity(N);
48			for _ in 0..N {
49				match (seq.next_element())? {
50					Some(val) => data.push(val),
51					None => return Err(serde::de::Error::invalid_length(N, &self)),
52				}
53			}
54			match data.try_into() {
55				Ok(arr) => Ok(arr),
56				Err(_) => unreachable!(),
57			}
58		}
59	}
60
61	pub fn deserialize<'de, D, T, const N: usize>(deserializer: D) -> Result<[T; N], D::Error>
62	where
63		D: Deserializer<'de>,
64		T: Deserialize<'de>,
65	{
66		deserializer.deserialize_tuple(N, ArrayVisitor::<T, N>(PhantomData))
67	}
68}
69
70pub(crate) fn from_hex_to_bytes<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
71where
72	D: Deserializer<'de>,
73{
74	let s = String::deserialize(deserializer)?;
75
76	let str_without_0x = match s.strip_prefix("0x") {
77		Some(val) => val,
78		None => &s,
79	};
80
81	let hex_bytes = match hex::decode(str_without_0x) {
82		Ok(bytes) => bytes,
83		Err(e) => return Err(serde::de::Error::custom(e.to_string())),
84	};
85
86	Ok(hex_bytes)
87}
88
89pub(crate) fn from_int_to_u256<'de, D>(deserializer: D) -> Result<U256, D::Error>
90where
91	D: Deserializer<'de>,
92{
93	let number = u128::deserialize(deserializer)?;
94
95	Ok(U256::from(number))
96}
97
98pub struct HexVisitor<const LENGTH: usize>();
99
100impl<'de, const LENGTH: usize> serde::de::Visitor<'de> for HexVisitor<LENGTH> {
101	type Value = [u8; LENGTH];
102
103	fn expecting(&self, formatter: &mut Formatter) -> sp_std::fmt::Result {
104		formatter.write_str("a hex string with an '0x' prefix")
105	}
106
107	fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
108	where
109		E: serde::de::Error,
110	{
111		let stripped = match v.strip_prefix("0x") {
112			Some(stripped) => stripped,
113			None => v,
114		};
115
116		let decoded = match hex::decode(stripped) {
117			Ok(decoded) => decoded,
118			Err(e) => return Err(serde::de::Error::custom(e.to_string())),
119		};
120		if decoded.len() != LENGTH {
121			return Err(serde::de::Error::custom("publickey expected to be 48 characters"))
122		}
123
124		let data: Self::Value = decoded
125			.try_into()
126			.map_err(|_e| serde::de::Error::custom("hex data has unexpected length"))?;
127
128		Ok(data)
129	}
130}