topcoat_runtime/surrogate/
vec.rs1use 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#[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}