1use core::{
4 borrow::Borrow,
5 cmp, fmt, hash,
6 ops::{Deref, Index},
7 slice::SliceIndex,
8};
9
10use munge::munge;
11use rancor::Fallible;
12
13use crate::{
14 primitive::{ArchivedUsize, FixedUsize},
15 seal::Seal,
16 ser::{Allocator, Writer, WriterExt as _},
17 Archive, Place, Portable, RelPtr, Serialize, SerializeUnsized,
18};
19
20#[derive(Portable)]
26#[cfg_attr(
27 feature = "bytecheck",
28 derive(bytecheck::CheckBytes),
29 bytecheck(verify)
30)]
31#[rkyv(crate)]
32#[repr(C)]
33pub struct ArchivedVec<T> {
34 ptr: RelPtr<T>,
35 len: ArchivedUsize,
36}
37
38impl<T> ArchivedVec<T> {
39 pub fn as_ptr(&self) -> *const T {
41 unsafe { self.ptr.as_ptr() }
42 }
43
44 pub fn len(&self) -> usize {
46 self.len.to_native() as usize
47 }
48
49 pub fn is_empty(&self) -> bool {
51 self.len() == 0
52 }
53
54 pub fn as_slice(&self) -> &[T] {
56 unsafe { core::slice::from_raw_parts(self.as_ptr(), self.len()) }
57 }
58
59 pub fn as_slice_seal(this: Seal<'_, Self>) -> Seal<'_, [T]> {
61 let len = this.len();
62 munge!(let Self { ptr, .. } = this);
63 let slice = unsafe {
64 core::slice::from_raw_parts_mut(RelPtr::as_mut_ptr(ptr), len)
65 };
66 Seal::new(slice)
67 }
68
69 pub fn resolve_from_slice<U: Archive<Archived = T>>(
71 slice: &[U],
72 resolver: VecResolver,
73 out: Place<Self>,
74 ) {
75 Self::resolve_from_len(slice.len(), resolver, out);
76 }
77
78 pub fn resolve_from_len(
80 len: usize,
81 resolver: VecResolver,
82 out: Place<Self>,
83 ) {
84 munge!(let ArchivedVec { ptr, len: out_len } = out);
85 RelPtr::emplace(resolver.pos as usize, ptr);
86 usize::resolve(&len, (), out_len);
87 }
88
89 pub fn serialize_from_slice<
91 U: Serialize<S, Archived = T>,
92 S: Fallible + Allocator + Writer + ?Sized,
93 >(
94 slice: &[U],
95 serializer: &mut S,
96 ) -> Result<VecResolver, S::Error> {
97 Ok(VecResolver {
98 pos: slice.serialize_unsized(serializer)? as FixedUsize,
99 })
100 }
101
102 pub fn serialize_from_iter<U, I, S>(
108 iter: I,
109 serializer: &mut S,
110 ) -> Result<VecResolver, S::Error>
111 where
112 U: Serialize<S, Archived = T>,
113 I: ExactSizeIterator + Clone,
114 I::Item: Borrow<U>,
115 S: Fallible + Allocator + Writer + ?Sized,
116 {
117 use crate::util::SerVec;
118
119 SerVec::with_capacity(
120 serializer,
121 iter.len(),
122 |resolvers, serializer| {
123 for value in iter.clone() {
124 let resolver = value.borrow().serialize(serializer)?;
125 resolvers.push(resolver);
126 }
127
128 let pos = serializer.align_for::<T>()?;
129 for (value, resolver) in iter.zip(resolvers.drain()) {
130 unsafe {
131 serializer.resolve_aligned(value.borrow(), resolver)?;
132 }
133 }
134
135 Ok(VecResolver {
136 pos: pos as FixedUsize,
137 })
138 },
139 )?
140 }
141
142 pub fn serialize_from_unknown_length_iter<B, I, S>(
150 iter: &mut I,
151 serializer: &mut S,
152 ) -> Result<VecResolver, S::Error>
153 where
154 B: Serialize<S, Archived = T>,
155 I: Iterator<Item = B>,
156 S: Fallible + Allocator + Writer + ?Sized,
157 {
158 unsafe {
159 let pos = serializer.align_for::<T>()?;
160
161 for value in iter {
162 let pos_cached = serializer.pos();
163 let resolver = value.serialize(serializer)?;
164 assert!(serializer.pos() == pos_cached);
165 serializer.resolve_aligned(value.borrow(), resolver)?;
166 }
167
168 Ok(VecResolver {
169 pos: pos as FixedUsize,
170 })
171 }
172 }
173}
174
175impl<T> AsRef<[T]> for ArchivedVec<T> {
176 fn as_ref(&self) -> &[T] {
177 self.as_slice()
178 }
179}
180
181impl<T> Borrow<[T]> for ArchivedVec<T> {
182 fn borrow(&self) -> &[T] {
183 self.as_slice()
184 }
185}
186
187impl<T: fmt::Debug> fmt::Debug for ArchivedVec<T> {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 f.debug_list().entries(self.as_slice()).finish()
190 }
191}
192
193impl<T> Deref for ArchivedVec<T> {
194 type Target = [T];
195
196 fn deref(&self) -> &Self::Target {
197 self.as_slice()
198 }
199}
200
201impl<T: Eq> Eq for ArchivedVec<T> {}
202
203impl<T: hash::Hash> hash::Hash for ArchivedVec<T> {
204 fn hash<H: hash::Hasher>(&self, state: &mut H) {
205 self.as_slice().hash(state)
206 }
207}
208
209impl<T, I: SliceIndex<[T]>> Index<I> for ArchivedVec<T> {
210 type Output = <[T] as Index<I>>::Output;
211
212 fn index(&self, index: I) -> &Self::Output {
213 self.as_slice().index(index)
214 }
215}
216
217impl<T: Ord> Ord for ArchivedVec<T> {
218 fn cmp(&self, other: &Self) -> cmp::Ordering {
219 self.as_slice().cmp(other.as_slice())
220 }
221}
222
223impl<T: PartialEq<U>, U> PartialEq<ArchivedVec<U>> for ArchivedVec<T> {
224 fn eq(&self, other: &ArchivedVec<U>) -> bool {
225 self.as_slice().eq(other.as_slice())
226 }
227}
228
229impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for ArchivedVec<T> {
230 fn eq(&self, other: &[U; N]) -> bool {
231 self.as_slice().eq(&other[..])
232 }
233}
234
235impl<T: PartialEq<U>, U, const N: usize> PartialEq<ArchivedVec<T>> for [U; N] {
236 fn eq(&self, other: &ArchivedVec<T>) -> bool {
237 other.eq(self)
238 }
239}
240
241impl<T: PartialEq<U>, U> PartialEq<[U]> for ArchivedVec<T> {
242 fn eq(&self, other: &[U]) -> bool {
243 self.as_slice().eq(other)
244 }
245}
246
247impl<T: PartialEq<U>, U> PartialEq<ArchivedVec<U>> for [T] {
248 fn eq(&self, other: &ArchivedVec<U>) -> bool {
249 self.eq(other.as_slice())
250 }
251}
252
253impl<T: PartialOrd> PartialOrd<ArchivedVec<T>> for ArchivedVec<T> {
254 fn partial_cmp(&self, other: &ArchivedVec<T>) -> Option<cmp::Ordering> {
255 self.as_slice().partial_cmp(other.as_slice())
256 }
257}
258
259impl<T: PartialOrd> PartialOrd<[T]> for ArchivedVec<T> {
260 fn partial_cmp(&self, other: &[T]) -> Option<cmp::Ordering> {
261 self.as_slice().partial_cmp(other)
262 }
263}
264
265impl<T: PartialOrd> PartialOrd<ArchivedVec<T>> for [T] {
266 fn partial_cmp(&self, other: &ArchivedVec<T>) -> Option<cmp::Ordering> {
267 self.partial_cmp(other.as_slice())
268 }
269}
270
271pub struct VecResolver {
273 pos: FixedUsize,
274}
275
276impl VecResolver {
277 pub fn from_pos(pos: usize) -> Self {
280 Self {
281 pos: pos as FixedUsize,
282 }
283 }
284}
285
286#[cfg(feature = "bytecheck")]
287mod verify {
288 use bytecheck::{
289 rancor::{Fallible, Source},
290 CheckBytes, Verify,
291 };
292
293 use crate::{
294 validation::{ArchiveContext, ArchiveContextExt},
295 vec::ArchivedVec,
296 };
297
298 unsafe impl<T, C> Verify<C> for ArchivedVec<T>
299 where
300 T: CheckBytes<C>,
301 C: Fallible + ArchiveContext + ?Sized,
302 C::Error: Source,
303 {
304 fn verify(&self, context: &mut C) -> Result<(), C::Error> {
305 let ptr = core::ptr::slice_from_raw_parts(
306 self.ptr.as_ptr_wrapping(),
307 self.len.to_native() as usize,
308 );
309
310 context.in_subtree(ptr, |context| unsafe {
311 <[T]>::check_bytes(ptr, context)
312 })
313 }
314 }
315}