Skip to main content

topcoat_runtime/surrogate/
array.rs

1use 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/// A fixed-size sequence of runtime values.
10#[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}