Skip to main content

topcoat_runtime/surrogate/
vec.rs

1use std::ops::Deref;
2
3use ref_cast::RefCast;
4use serde::Deserialize;
5
6use super::sequence::deserialize_sequence;
7use crate::{SliceSurrogate, Surrogated, impl_surrogate, impl_surrogate_mut, impl_surrogate_ref};
8
9/// An owned sequence of runtime values.
10#[derive(Debug, Clone, RefCast)]
11#[repr(transparent)]
12pub struct VecSurrogate<T>(Vec<T>);
13
14impl<T> VecSurrogate<T> {
15    pub(crate) const fn new(value: Vec<T>) -> 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> Deref for VecSurrogate<T> {
26    type Target = SliceSurrogate<T>;
27
28    fn deref(&self) -> &Self::Target {
29        self.as_slice()
30    }
31}
32
33impl_surrogate!({T} Vec<T>, VecSurrogate<T>);
34impl_surrogate_ref!({T} Vec<T>, VecSurrogate<T>);
35impl_surrogate_mut!({T} Vec<T>, VecSurrogate<T>);
36
37impl<T> serde::Serialize for VecSurrogate<T>
38where
39    for<'a> &'a T: Surrogated,
40    for<'a> <&'a T as Surrogated>::Surrogate: serde::Serialize,
41{
42    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43    where
44        S: serde::Serializer,
45    {
46        self.as_slice().serialize_with_tag(serializer, "Vec")
47    }
48}
49
50impl<'de, T> Deserialize<'de> for VecSurrogate<T>
51where
52    T: Surrogated,
53    T::Surrogate: Deserialize<'de>,
54{
55    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
56    where
57        D: serde::Deserializer<'de>,
58    {
59        deserialize_sequence(deserializer, "Vec").map(Self)
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use serde_json::json;
66
67    use super::*;
68    use crate::Surrogate;
69
70    #[test]
71    fn serializes_owned_and_borrowed_sequences_through_element_surrogates() {
72        let values = vec![0u128, u128::MAX];
73        let elements = json!([
74            { "t": "u128", "bits": 128, "v": "0" },
75            { "t": "u128", "bits": 128, "v": u128::MAX.to_string() },
76        ]);
77        let owned = values.clone().into_surrogate();
78        let wire = json!({ "t": "Vec", "bits": usize::BITS, "v": elements });
79        assert_eq!(serde_json::to_value(&owned).unwrap(), wire);
80        assert_eq!(
81            serde_json::to_value((&values).into_surrogate()).unwrap(),
82            wire
83        );
84        let decoded: VecSurrogate<u128> = serde_json::from_value(wire).unwrap();
85        assert_eq!(decoded.into_real(), values);
86        assert_eq!(
87            serde_json::to_value(values.as_slice().into_surrogate()).unwrap(),
88            json!({ "t": "Slice", "bits": usize::BITS, "v": elements }),
89        );
90    }
91
92    #[test]
93    fn round_trips_empty_and_nested_vectors() {
94        for values in [
95            vec![],
96            vec![vec![], vec![Some(42u64), None, Some(u64::MAX)]],
97        ] {
98            let wire = serde_json::to_value(values.clone().into_surrogate()).unwrap();
99            let decoded: VecSurrogate<Vec<Option<u64>>> = serde_json::from_value(wire).unwrap();
100            assert_eq!(decoded.into_real(), values);
101        }
102    }
103
104    #[test]
105    fn rejects_invalid_payloads() {
106        for wire in [
107            json!([]),
108            json!({ "t": "Slice", "bits": usize::BITS, "v": [] }),
109            json!({ "t": "Vec", "bits": 128, "v": [] }),
110            json!({ "t": "Vec", "bits": usize::BITS / 2, "v": [] }),
111            json!({ "t": "Vec", "v": [] }),
112            json!({ "t": "Vec", "bits": usize::BITS }),
113            json!({ "t": "Vec", "bits": usize::BITS, "v": null }),
114            json!({ "t": "Vec", "bits": usize::BITS, "v": [], "extra": true }),
115            json!({ "t": "Vec", "bits": usize::BITS, "v": [42] }),
116            json!({ "t": "Vec", "bits": usize::BITS, "v": [
117                { "t": "u8", "bits": 8, "v": "256" }
118            ] }),
119        ] {
120            assert!(serde_json::from_value::<VecSurrogate<u8>>(wire).is_err());
121        }
122    }
123
124    #[test]
125    fn methods_borrow_elements_and_clone_owned_storage() {
126        let surrogate = vec![String::from("hello"), String::from("world")].into_surrogate();
127        assert_eq!(surrogate.len().into_real(), 2);
128        assert!(!surrogate.is_empty().into_real());
129        let first = surrogate.first().into_real().unwrap();
130        assert!(std::ptr::eq(first, surrogate.0.first().unwrap()));
131        assert_eq!(surrogate.last().into_real(), Some(&surrogate.0[1]));
132        assert!(surrogate.get(2usize.into_surrogate()).into_real().is_none());
133        assert!(
134            surrogate
135                .get(usize::MAX.into_surrogate())
136                .into_real()
137                .is_none()
138        );
139        let mut copy = surrogate.as_slice().to_owned().into_real();
140        copy[0].push('!');
141        assert_eq!(first, "hello");
142        let mut values = vec![42u8];
143        assert_eq!(values.as_mut_slice().into_surrogate().len().into_real(), 1);
144    }
145}