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