pythnet_sdk/wire/
array.rs1use {
15 serde::{
16 Deserialize,
17 Serialize,
18 Serializer,
19 },
20 std::mem::MaybeUninit,
21};
22
23pub fn serialize<S, T, const N: usize>(array: &[T; N], serializer: S) -> Result<S::Ok, S::Error>
25where
26 S: Serializer,
27 T: Serialize,
28{
29 use serde::ser::SerializeTuple;
30 let mut seq = serializer.serialize_tuple(N)?;
31 array.iter().try_for_each(|e| seq.serialize_element(e))?;
32 seq.end()
33}
34
35struct ArrayVisitor<T, const N: usize> {
38 _marker: std::marker::PhantomData<T>,
39}
40
41impl<'de, T, const N: usize> serde::de::Visitor<'de> for ArrayVisitor<T, N>
44where
45 T: Deserialize<'de>,
46{
47 type Value = [T; N];
48
49 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
50 write!(formatter, "an array of length {N}")
51 }
52
53 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
54 where
55 A: serde::de::SeqAccess<'de>,
56 {
57 let mut array = MaybeUninit::<[T; N]>::uninit();
61 let ptr = array.as_mut_ptr() as *mut T;
62 let mut pos = 0;
63 while pos < N {
64 let next = seq
65 .next_element()?
66 .ok_or_else(|| serde::de::Error::invalid_length(pos, &self))?;
67
68 unsafe {
69 std::ptr::write(ptr.add(pos), next);
70 }
71
72 pos += 1;
73 }
74
75 if pos == N {
78 return Ok(unsafe { array.assume_init() });
79 }
80
81 Err(serde::de::Error::invalid_length(pos, &self))
82 }
83}
84
85pub fn deserialize<'de, D, T, const N: usize>(deserializer: D) -> Result<[T; N], D::Error>
87where
88 D: serde::Deserializer<'de>,
89 T: serde::de::Deserialize<'de>,
90{
91 deserializer.deserialize_tuple(
92 N,
93 ArrayVisitor {
94 _marker: std::marker::PhantomData,
95 },
96 )
97}