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