spinoso_array/lib.rs
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
#![warn(clippy::all)]
#![warn(clippy::pedantic)]
#![warn(clippy::cargo)]
#![allow(unknown_lints)]
#![allow(clippy::manual_let_else)]
#![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(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))]
//! Contiguous growable vector types that implement the [Ruby `Array`] API.
//!
//! `Array` types are growable vectors with potentially heap-allocated contents.
//! The types in this crate can be passed by pointer over FFI.
//!
//! `Array` types implement the mutating APIs in the Ruby `Array` core class as
//! well as indexing and slicing APIs.
//!
//! `spinoso-array` is part of a [collection of crates] that implement the data
//! structures that comprise the Ruby Core and Standard Library implementation
//! for [Artichoke Ruby].
//!
//! # Array types
//!
//! - [`Array`] is based on [`Vec`] from the Rust `alloc` crate and standard
//! library. This Spinoso array type is enabled by default.
#![cfg_attr(
feature = "small-array",
doc = "- [`SmallArray`] is based on [`SmallVec`] and implements the small vector"
)]
#![cfg_attr(
feature = "small-array",
doc = " optimization – small arrays are stored inline without a heap allocation."
)]
#![cfg_attr(
feature = "small-array",
doc = " This Spinoso array type requires the **small-array** Cargo feature."
)]
#![cfg_attr(
feature = "tiny-array",
doc = "- [`TinyArray`] is based on [`TinyVec`] and implements the small vector"
)]
#![cfg_attr(
feature = "tiny-array",
doc = " optimization – small arrays are stored inline without a heap allocation."
)]
#![cfg_attr(
feature = "tiny-array",
doc = " This Spinoso array type requires the **tiny-array** Cargo feature."
)]
//!
//!
//! # `no_std`
//!
//! This crate is `no_std` with a required dependency on the [`alloc`] crate.
//!
//! # Examples
//!
//! You can create an [`Array<T>`](Array) with [`new`](Array::new):
//!
//! ```
//! # use spinoso_array::Array;
//! let ary: Array<i32> = Array::new();
//! ```
//!
//! Or with one of the many [`From`] and [`FromIterator`] implementations:
//!
//! ```
//! # use core::iter;
//! # use spinoso_array::Array;
//! let ary: Array<i32> = Array::from(vec![1, 2, 3, 4]);
//! let ary2: Array<i32> = iter::repeat(1).take(10).collect();
//! ```
//!
//! You can [`push`](Array::push) values onto the end of an array (which will
//! grow the array as needed):
//!
//! ```
//! # use spinoso_array::Array;
//! let mut ary = Array::from(&[1, 2]);
//! ary.push(3);
//! ```
//!
//! Popping values behaves similarly:
//!
//! ```
//! # use spinoso_array::Array;
//! let mut ary = Array::from(&[1, 2]);
//! assert_eq!(ary.pop(), Some(2));
//! ```
//!
//! Arrays also support indexing (through the [`Index`] and [`IndexMut`]
//! traits):
//!
//! ```
//! # use spinoso_array::Array;
//! let mut a = Array::from(&[1, 2, 3]);
//! let three = a[2];
//! a[1] = a[1] + 5;
//! ```
//!
//! The `Array` vector types in this crate differ from [`Vec`] in the Rust `std`
//! by offering many specialized slicing and mutation APIs. For example, rather
//! than offering APIs like [`Vec::drain`] and [`Vec::splice`], array types in
//! this crate offer specialized methods like [`shift`], [`shift_n`],
//! [`unshift`], and [`unshift_n`] and `splice`-like methods with
//! [`insert_slice`], and [`set_slice`].
//!
//! ```
//! # use spinoso_array::Array;
//! let mut a = Array::from(&[1, 2, 3]);
//! a.unshift(0);
//! assert_eq!(a, [0, 1, 2, 3]);
//! let b = a.shift_n(10);
//! assert_eq!(a, []);
//! assert_eq!(b, [0, 1, 2, 3]);
//! ```
//!
//! # Panics
//!
//! `Array`s in this crate do not expose panicking slicing operations (except for
//! their [`Index`] and [`IndexMut`] implementations). Instead of panicking,
//! slicing APIs operate until the end of the vector or return `&[]`. Mutating
//! APIs extend `Array`s on out of bounds access.
//!
//! [Ruby `Array`]: https://ruby-doc.org/core-3.1.2/Array.html
//! [collection of crates]: https://crates.io/keywords/spinoso
//! [Artichoke Ruby]: https://www.artichokeruby.org/
//! [`Vec`]: alloc::vec::Vec
#![cfg_attr(feature = "small-array", doc = "[`SmallVec`]: smallvec::SmallVec")]
#![cfg_attr(feature = "tiny-array", doc = "[`TinyVec`]: tinyvec::TinyVec")]
//! [`From`]: core::convert::From
//! [`FromIterator`]: core::iter::FromIterator
//! [`Index`]: core::ops::Index
//! [`IndexMut`]: core::ops::IndexMut
//! [`Vec::drain`]: alloc::vec::Vec::drain
//! [`Vec::splice`]: alloc::vec::Vec::splice
//! [`shift`]: Array::shift
//! [`shift_n`]: Array::shift_n
//! [`unshift`]: Array::unshift
//! [`unshift_n`]: Array::unshift_n
//! [`insert_slice`]: Array::insert_slice
//! [`set_slice`]: Array::set_slice
// This crate is `no_std` + `alloc`
#![no_std]
// Ensure code blocks in `README.md` compile
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
mod readme {}
extern crate alloc;
mod array;
#[cfg(feature = "small-array")]
pub use array::smallvec::SmallArray;
#[cfg(feature = "tiny-array")]
pub use array::tinyvec::TinyArray;
pub use array::vec::{Array, RawParts};
#[cfg(any(feature = "small-array", feature = "tiny-array"))]
pub use array::INLINE_CAPACITY;