topcoat_runtime/surrogate/
array.rs1use std::ops::Deref;
2
3use ref_cast::RefCast;
4use serde::{Deserialize, de};
5
6use super::sequence::deserialize_sequence;
7use crate::{SliceSurrogate, Surrogated, impl_surrogate, impl_surrogate_mut, impl_surrogate_ref};
8
9#[derive(Debug, Clone, Copy, RefCast)]
11#[repr(transparent)]
12pub struct ArraySurrogate<T, const N: usize>([T; N]);
13
14impl<T, const N: usize> ArraySurrogate<T, N> {
15 pub(crate) const fn new(value: [T; N]) -> Self {
16 Self(value)
17 }
18
19 #[must_use]
20 pub fn as_slice(&self) -> &SliceSurrogate<T> {
21 SliceSurrogate::ref_cast(self.0.as_slice())
22 }
23}
24
25impl<T: Clone, const N: usize> ArraySurrogate<T, N> {
26 #[must_use]
27 pub fn to_owned(&self) -> Self {
28 self.clone()
29 }
30}
31
32impl<T, const N: usize> Deref for ArraySurrogate<T, N> {
33 type Target = SliceSurrogate<T>;
34
35 fn deref(&self) -> &Self::Target {
36 self.as_slice()
37 }
38}
39
40impl_surrogate!({T, const N: usize} [T; N], ArraySurrogate<T, N>);
41impl_surrogate_ref!({T, const N: usize} [T; N], ArraySurrogate<T, N>);
42impl_surrogate_mut!({T, const N: usize} [T; N], ArraySurrogate<T, N>);
43
44impl<T, const N: usize> serde::Serialize for ArraySurrogate<T, N>
45where
46 for<'a> &'a T: Surrogated,
47 for<'a> <&'a T as Surrogated>::Surrogate: serde::Serialize,
48{
49 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50 where
51 S: serde::Serializer,
52 {
53 self.as_slice().serialize_with_tag(serializer, "Array")
54 }
55}
56
57impl<'de, T, const N: usize> Deserialize<'de> for ArraySurrogate<T, N>
58where
59 T: Surrogated,
60 T::Surrogate: Deserialize<'de>,
61{
62 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63 where
64 D: serde::Deserializer<'de>,
65 {
66 let elements: Vec<T> = deserialize_sequence(deserializer, "Array")?;
67 let values = elements.try_into().map_err(|values: Vec<T>| {
68 de::Error::custom(format_args!(
69 "expected {N} array elements, got {}",
70 values.len()
71 ))
72 })?;
73 Ok(Self(values))
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use serde_json::json;
80
81 use super::*;
82 use crate::Surrogate;
83
84 #[test]
85 fn round_trips_arrays_of_any_length() {
86 fn check<const N: usize>(values: [u128; N]) {
87 let surrogate = values.into_surrogate();
88 let wire = serde_json::to_value(surrogate).unwrap();
89 assert_eq!(wire["t"], "Array");
90 assert_eq!(wire["bits"], usize::BITS);
91 let decoded: ArraySurrogate<u128, N> = serde_json::from_value(wire).unwrap();
92 assert_eq!(decoded.into_real(), values);
93 assert_eq!(surrogate.to_owned().into_real(), values);
94 assert_eq!(surrogate.to_vec().into_real(), values);
95 }
96 check([]);
97 check([u128::MAX]);
98 check([42; 64]);
99 }
100
101 #[test]
102 fn rejects_wrong_lengths_and_collection_kinds() {
103 for wire in [
104 json!({ "t": "Array", "bits": usize::BITS, "v": [] }),
105 json!({ "t": "Array", "bits": usize::BITS, "v": [true, false] }),
106 json!({ "t": "Vec", "bits": usize::BITS, "v": [true] }),
107 json!({ "t": "Slice", "bits": usize::BITS, "v": [true] }),
108 ] {
109 assert!(serde_json::from_value::<ArraySurrogate<bool, 1>>(wire).is_err());
110 }
111 }
112}