raw_parts/lib.rs
1#![warn(clippy::all)]
2#![warn(clippy::pedantic)]
3#![warn(clippy::cargo)]
4#![allow(clippy::option_if_let_else)]
5#![allow(unknown_lints)]
6#![warn(missing_docs)]
7#![warn(missing_debug_implementations)]
8#![warn(missing_copy_implementations)]
9#![warn(rust_2018_idioms)]
10#![warn(rust_2021_compatibility)]
11#![warn(trivial_casts, trivial_numeric_casts)]
12#![warn(unsafe_op_in_unsafe_fn)]
13#![warn(unused_qualifications)]
14#![warn(variant_size_differences)]
15// Enable feature callouts in generated documentation:
16// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
17//
18// This approach is borrowed from tokio.
19#![cfg_attr(docsrs, feature(doc_cfg))]
20#![cfg_attr(docsrs, feature(doc_alias))]
21
22//! A wrapper around the decomposed parts of a `Vec<T>`.
23//!
24//! This crate defines a struct that contains the `Vec`'s internal pointer,
25//! length, and allocated capacity.
26//!
27//! [`RawParts`] makes [`Vec::from_raw_parts`] and [`Vec::into_raw_parts`] easier
28//! to use by giving names to the returned values. This prevents errors from
29//! mixing up the two `usize` values of length and capacity.
30//!
31//! # Examples
32//!
33//! ```
34//! use raw_parts::RawParts;
35//!
36//! let v: Vec<i32> = vec![-1, 0, 1];
37//!
38//! let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
39//!
40//! let rebuilt = unsafe {
41//! // We can now make changes to the components, such as
42//! // transmuting the raw pointer to a compatible type.
43//! let ptr = ptr as *mut u32;
44//! let raw_parts = RawParts { ptr, length, capacity };
45//!
46//! raw_parts.into_vec()
47//! };
48//! assert_eq!(rebuilt, [4294967295, 0, 1]);
49//! ```
50//!
51//! # `no_std`
52//!
53//! raw-parts is `no_std` compatible with a required dependency on [`alloc`].
54
55#![no_std]
56#![doc(html_root_url = "https://docs.rs/raw-parts/2.2.0")]
57
58extern crate alloc;
59
60use alloc::vec::Vec;
61use core::fmt;
62use core::hash::{Hash, Hasher};
63use core::mem::ManuallyDrop;
64
65/// A wrapper around the decomposed parts of a `Vec<T>`.
66///
67/// This struct contains the `Vec`'s internal pointer, length, and allocated
68/// capacity.
69///
70/// `RawParts` makes [`Vec::from_raw_parts`] and [`Vec::into_raw_parts`] easier
71/// to use by giving names to the returned values. This prevents errors from
72/// mixing up the two `usize` values of length and capacity.
73///
74/// # Examples
75///
76/// ```
77/// use raw_parts::RawParts;
78///
79/// let v: Vec<i32> = vec![-1, 0, 1];
80///
81/// let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
82///
83/// let rebuilt = unsafe {
84/// // We can now make changes to the components, such as
85/// // transmuting the raw pointer to a compatible type.
86/// let ptr = ptr as *mut u32;
87/// let raw_parts = RawParts { ptr, length, capacity };
88///
89/// raw_parts.into_vec()
90/// };
91/// assert_eq!(rebuilt, [4294967295, 0, 1]);
92/// ```
93pub struct RawParts<T> {
94 /// A non-null pointer to a buffer of `T`.
95 ///
96 /// This pointer is the same as the value returned by [`Vec::as_mut_ptr`] in
97 /// the source vector.
98 pub ptr: *mut T,
99 /// The number of elements in the source vector, also referred to as its
100 /// "length".
101 ///
102 /// This value is the same as the value returned by [`Vec::len`] in the
103 /// source vector.
104 pub length: usize,
105 /// The number of elements the source vector can hold without reallocating.
106 ///
107 /// This value is the same as the value returned by [`Vec::capacity`] in the
108 /// source vector.
109 pub capacity: usize,
110}
111
112impl<T> From<Vec<T>> for RawParts<T> {
113 /// Decompose a `Vec<T>` into its raw components.
114 fn from(vec: Vec<T>) -> Self {
115 Self::from_vec(vec)
116 }
117}
118
119impl<T> fmt::Debug for RawParts<T> {
120 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
121 fmt.debug_struct("RawParts")
122 .field("ptr", &self.ptr)
123 .field("length", &self.length)
124 .field("capacity", &self.capacity)
125 .finish()
126 }
127}
128
129impl<T> PartialEq for RawParts<T> {
130 fn eq(&self, other: &Self) -> bool {
131 self.ptr == other.ptr && self.length == other.length && self.capacity == other.capacity
132 }
133}
134
135impl<T> Eq for RawParts<T> {}
136
137impl<T> Hash for RawParts<T> {
138 fn hash<H: Hasher>(&self, state: &mut H) {
139 self.ptr.hash(state);
140 self.length.hash(state);
141 self.capacity.hash(state);
142 }
143}
144
145// Do not implement the `From` trait in the other direction since `crate::from`
146// is an unsafe function.
147//
148// ```
149// impl<T> From<RawParts<T>> for Vec<T> {
150// fn from(raw_parts: RawParts<T>) -> Self {
151// // ERROR: this requires `unsafe`, which we don't want to hide in a
152// // `From` impl.
153// from(raw_parts)
154// }
155// }
156
157impl<T> RawParts<T> {
158 /// Construct the raw components of a `Vec<T>` by decomposing it.
159 ///
160 /// Returns a struct containing the raw pointer to the underlying data, the
161 /// length of the vector (in elements), and the allocated capacity of the
162 /// data (in elements).
163 ///
164 /// After calling this function, the caller is responsible for the memory
165 /// previously managed by the `Vec`. The only way to do this is to convert
166 /// the raw pointer, length, and capacity back into a `Vec` with the
167 /// [`Vec::from_raw_parts`] function or the [`into_vec`] function, allowing
168 /// the destructor to perform the cleanup.
169 ///
170 /// [`into_vec`]: Self::into_vec
171 ///
172 /// # Examples
173 ///
174 /// ```
175 /// use raw_parts::RawParts;
176 ///
177 /// let v: Vec<i32> = vec![-1, 0, 1];
178 ///
179 /// let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
180 ///
181 /// let rebuilt = unsafe {
182 /// // We can now make changes to the components, such as
183 /// // transmuting the raw pointer to a compatible type.
184 /// let ptr = ptr as *mut u32;
185 /// let raw_parts = RawParts { ptr, length, capacity };
186 ///
187 /// raw_parts.into_vec()
188 /// };
189 /// assert_eq!(rebuilt, [4294967295, 0, 1]);
190 /// ```
191 #[must_use]
192 pub fn from_vec(vec: Vec<T>) -> Self {
193 // FIXME Update this when vec_into_raw_parts is stabilized
194 // See: https://doc.rust-lang.org/1.69.0/src/alloc/vec/mod.rs.html#823-826
195 // See: https://doc.rust-lang.org/beta/unstable-book/library-features/vec-into-raw-parts.html
196 //
197 // https://github.com/rust-lang/rust/issues/65816
198 let mut me = ManuallyDrop::new(vec);
199 let (ptr, length, capacity) = (me.as_mut_ptr(), me.len(), me.capacity());
200
201 Self {
202 ptr,
203 length,
204 capacity,
205 }
206 }
207
208 /// Creates a `Vec<T>` directly from the raw components of another vector.
209 ///
210 /// # Safety
211 ///
212 /// This function has the same safety invariants as [`Vec::from_raw_parts`],
213 /// which are repeated in the following paragraphs.
214 ///
215 /// This is highly unsafe, due to the number of invariants that aren't
216 /// checked:
217 ///
218 /// * `ptr` must have been allocated using the global allocator, such as via
219 /// the [`alloc::alloc`] function.
220 /// * `T` needs to have the same alignment as what `ptr` was allocated with.
221 /// (`T` having a less strict alignment is not sufficient, the alignment really
222 /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
223 /// allocated and deallocated with the same layout.)
224 /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
225 /// to be the same size as the pointer was allocated with. (Because similar to
226 /// alignment, [`dealloc`] must be called with the same layout `size`.)
227 /// * `length` needs to be less than or equal to `capacity`.
228 /// * The first `length` values must be properly initialized values of type `T`.
229 /// * `capacity` needs to be the capacity that the pointer was allocated with.
230 /// * The allocated size in bytes must be no larger than `isize::MAX`.
231 /// See the safety documentation of [`pointer::offset`].
232 ///
233 /// These requirements are always upheld by any `ptr` that has been allocated
234 /// via `Vec<T>`. Other allocation sources are allowed if the invariants are
235 /// upheld.
236 ///
237 /// Violating these may cause problems like corrupting the allocator's
238 /// internal data structures. For example it is normally **not** safe
239 /// to build a `Vec<u8>` from a pointer to a C `char` array with length
240 /// `size_t`, doing so is only safe if the array was initially allocated by
241 /// a `Vec` or `String`.
242 /// It's also not safe to build one from a `Vec<u16>` and its length, because
243 /// the allocator cares about the alignment, and these two types have different
244 /// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
245 /// turning it into a `Vec<u8>` it'll be deallocated with alignment 1. To avoid
246 /// these issues, it is often preferable to do casting/transmuting using
247 /// [`slice::from_raw_parts`] instead.
248 ///
249 /// The ownership of `ptr` is effectively transferred to the
250 /// `Vec<T>` which may then deallocate, reallocate or change the
251 /// contents of memory pointed to by the pointer at will. Ensure
252 /// that nothing else uses the pointer after calling this
253 /// function.
254 ///
255 /// [`String`]: alloc::string::String
256 /// [`alloc::alloc`]: alloc::alloc::alloc
257 /// [`dealloc`]: alloc::alloc::GlobalAlloc::dealloc
258 /// [`slice::from_raw_parts`]: core::slice::from_raw_parts
259 /// [`pointer::offset`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset
260 ///
261 /// # Examples
262 ///
263 /// ```
264 /// use core::ptr;
265 /// use core::mem;
266 ///
267 /// use raw_parts::RawParts;
268 ///
269 /// let v = vec![1, 2, 3];
270 ///
271 /// // Pull out the various important pieces of information about `v`
272 /// let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
273 ///
274 /// unsafe {
275 /// // Overwrite memory with 4, 5, 6
276 /// for i in 0..length as isize {
277 /// ptr::write(ptr.offset(i), 4 + i);
278 /// }
279 ///
280 /// // Put everything back together into a Vec
281 /// let raw_parts = RawParts { ptr, length, capacity };
282 /// let rebuilt = raw_parts.into_vec();
283 /// assert_eq!(rebuilt, [4, 5, 6]);
284 /// }
285 /// ```
286 #[must_use]
287 pub unsafe fn into_vec(self) -> Vec<T> {
288 let Self {
289 ptr,
290 length,
291 capacity,
292 } = self;
293
294 // Safety:
295 //
296 // The safety invariants that callers must uphold when calling `from` match
297 // the safety invariants of `Vec::from_raw_parts`.
298 unsafe { Vec::from_raw_parts(ptr, length, capacity) }
299 }
300}
301
302#[cfg(test)]
303mod tests {
304 use alloc::format;
305 use alloc::vec::Vec;
306 use core::hash::{Hash, Hasher};
307
308 use fnv::FnvHasher;
309
310 use crate::RawParts;
311
312 #[test]
313 fn roundtrip() {
314 let mut vec = Vec::with_capacity(100); // capacity is 100
315 vec.extend_from_slice(b"123456789"); // length is 9
316
317 let raw_parts = RawParts::from_vec(vec);
318 let raw_ptr = raw_parts.ptr;
319
320 let mut roundtripped_vec = unsafe { raw_parts.into_vec() };
321
322 assert_eq!(roundtripped_vec.capacity(), 100);
323 assert_eq!(roundtripped_vec.len(), 9);
324 assert_eq!(roundtripped_vec.as_mut_ptr(), raw_ptr);
325 }
326
327 #[test]
328 fn from_vec_sets_ptr() {
329 let mut vec = Vec::with_capacity(100); // capacity is 100
330 vec.extend_from_slice(b"123456789"); // length is 9
331 let ptr = vec.as_mut_ptr();
332
333 let raw_parts = RawParts::from_vec(vec);
334 assert_eq!(raw_parts.ptr, ptr);
335 }
336
337 #[test]
338 fn from_vec_sets_length() {
339 let mut vec = Vec::with_capacity(100); // capacity is 100
340 vec.extend_from_slice(b"123456789"); // length is 9
341
342 let raw_parts = RawParts::from_vec(vec);
343 assert_eq!(raw_parts.length, 9);
344 }
345
346 #[test]
347 fn from_vec_sets_capacity() {
348 let mut vec = Vec::with_capacity(100); // capacity is 100
349 vec.extend_from_slice(b"123456789"); // length is 9
350
351 let raw_parts = RawParts::from_vec(vec);
352 assert_eq!(raw_parts.capacity, 100);
353 }
354
355 #[test]
356 fn from_sets_ptr() {
357 let mut vec = Vec::with_capacity(100); // capacity is 100
358 vec.extend_from_slice(b"123456789"); // length is 9
359 let ptr = vec.as_mut_ptr();
360
361 let raw_parts = RawParts::from(vec);
362 assert_eq!(raw_parts.ptr, ptr);
363 }
364
365 #[test]
366 fn from_sets_length() {
367 let mut vec = Vec::with_capacity(100); // capacity is 100
368 vec.extend_from_slice(b"123456789"); // length is 9
369
370 let raw_parts = RawParts::from(vec);
371 assert_eq!(raw_parts.length, 9);
372 }
373
374 #[test]
375 fn from_sets_capacity() {
376 let mut vec = Vec::with_capacity(100); // capacity is 100
377 vec.extend_from_slice(b"123456789"); // length is 9
378
379 let raw_parts = RawParts::from(vec);
380 assert_eq!(raw_parts.capacity, 100);
381 }
382
383 #[test]
384 fn debug_test() {
385 let mut vec = Vec::with_capacity(100); // capacity is 100
386 vec.extend_from_slice(b"123456789"); // length is 9
387 let raw_parts = RawParts::from_vec(vec);
388
389 assert_eq!(
390 format!(
391 "RawParts {{ ptr: {:?}, length: 9, capacity: 100 }}",
392 raw_parts.ptr
393 ),
394 format!("{:?}", raw_parts)
395 );
396 }
397
398 #[test]
399 fn partial_eq_fail_pointer() {
400 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
401 vec_1.extend_from_slice(b"123456789"); // length is 9
402 let mut vec_2 = Vec::with_capacity(100); // capacity is 100
403 vec_2.extend_from_slice(b"123456789"); // length is 9
404
405 let raw_parts_1 = RawParts::from_vec(vec_1);
406 let raw_parts_2 = RawParts::from_vec(vec_2);
407 assert_ne!(raw_parts_1, raw_parts_2);
408 }
409
410 #[test]
411 fn partial_eq_fail_capacity() {
412 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
413 vec_1.extend_from_slice(b"123456789"); // length is 9
414 let mut vec_2 = Vec::with_capacity(101); // capacity is 101
415 vec_2.extend_from_slice(b"123456789"); // length is 9
416
417 let raw_parts_1 = RawParts::from_vec(vec_1);
418 let raw_parts_2 = RawParts::from_vec(vec_2);
419 assert_ne!(raw_parts_1, raw_parts_2);
420 }
421
422 #[test]
423 fn partial_eq_fail_length() {
424 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
425 vec_1.extend_from_slice(b"123456789"); // length is 9
426 let mut vec_2 = Vec::with_capacity(100); // capacity is 100
427 vec_2.extend_from_slice(b"12345678"); // length is 8
428
429 let raw_parts_1 = RawParts::from_vec(vec_1);
430 let raw_parts_2 = RawParts::from_vec(vec_2);
431 assert_ne!(raw_parts_1, raw_parts_2);
432 }
433
434 #[test]
435 fn partial_eq_pass() {
436 let mut vec = Vec::with_capacity(100); // capacity is 100
437 vec.extend_from_slice(b"123456789"); // length is 9
438
439 let RawParts {
440 ptr,
441 length,
442 capacity,
443 } = RawParts::from_vec(vec);
444 let a = RawParts {
445 ptr,
446 length,
447 capacity,
448 };
449 let b = RawParts {
450 ptr,
451 length,
452 capacity,
453 };
454 assert_eq!(a, b);
455 }
456
457 #[test]
458 fn hash_fail_pointer() {
459 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
460 vec_1.extend_from_slice(b"123456789"); // length is 9
461 let mut vec_2 = Vec::with_capacity(100); // capacity is 100
462 vec_2.extend_from_slice(b"123456789"); // length is 9
463
464 let raw_parts_1 = RawParts::from_vec(vec_1);
465 let mut hasher = FnvHasher::default();
466 raw_parts_1.hash(&mut hasher);
467 let hash_a = hasher.finish();
468
469 let raw_parts_2 = RawParts::from_vec(vec_2);
470 let mut hasher = FnvHasher::default();
471 raw_parts_2.hash(&mut hasher);
472 let hash_b = hasher.finish();
473
474 assert_ne!(hash_a, hash_b);
475 }
476
477 #[test]
478 fn hash_fail_capacity() {
479 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
480 vec_1.extend_from_slice(b"123456789"); // length is 9
481 let mut vec_2 = Vec::with_capacity(101); // capacity is 101
482 vec_2.extend_from_slice(b"123456789"); // length is 9
483
484 let raw_parts_1 = RawParts::from_vec(vec_1);
485 let mut hasher = FnvHasher::default();
486 raw_parts_1.hash(&mut hasher);
487 let hash_a = hasher.finish();
488
489 let raw_parts_2 = RawParts::from_vec(vec_2);
490 let mut hasher = FnvHasher::default();
491 raw_parts_2.hash(&mut hasher);
492 let hash_b = hasher.finish();
493
494 assert_ne!(hash_a, hash_b);
495 }
496
497 #[test]
498 fn hash_fail_length() {
499 let mut vec_1 = Vec::with_capacity(100); // capacity is 100
500 vec_1.extend_from_slice(b"123456789"); // length is 9
501 let mut vec_2 = Vec::with_capacity(100); // capacity is 100
502 vec_2.extend_from_slice(b"12345678"); // length is 8
503
504 let raw_parts_1 = RawParts::from_vec(vec_1);
505 let mut hasher = FnvHasher::default();
506 raw_parts_1.hash(&mut hasher);
507 let hash_a = hasher.finish();
508
509 let raw_parts_2 = RawParts::from_vec(vec_2);
510 let mut hasher = FnvHasher::default();
511 raw_parts_2.hash(&mut hasher);
512 let hash_b = hasher.finish();
513
514 assert_ne!(hash_a, hash_b);
515 }
516
517 #[test]
518 fn hash_eq_pass() {
519 let mut vec = Vec::with_capacity(100); // capacity is 100
520 vec.extend_from_slice(b"123456789"); // length is 9
521 let raw_parts = RawParts::from_vec(vec);
522
523 let mut hasher = FnvHasher::default();
524 raw_parts.hash(&mut hasher);
525 let hash_a = hasher.finish();
526
527 let mut hasher = FnvHasher::default();
528 raw_parts.hash(&mut hasher);
529 let hash_b = hasher.finish();
530
531 assert_eq!(hash_a, hash_b);
532 }
533}
534
535// Ensure code blocks in `README.md` compile.
536//
537// This module declaration should be kept at the end of the file, in order to
538// not interfere with code coverage.
539#[cfg(doctest)]
540#[doc = include_str!("../README.md")]
541mod readme {}