spinoso_array/
lib.rs

1#![warn(clippy::all, clippy::pedantic, clippy::undocumented_unsafe_blocks)]
2#![allow(
3    clippy::let_underscore_untyped,
4    reason = "https://github.com/rust-lang/rust-clippy/pull/10442#issuecomment-1516570154"
5)]
6#![allow(
7    clippy::question_mark,
8    reason = "https://github.com/rust-lang/rust-clippy/issues/8281"
9)]
10#![allow(clippy::manual_let_else, reason = "manual_let_else was very buggy on release")]
11#![allow(clippy::missing_errors_doc, reason = "A lot of existing code fails this lint")]
12#![allow(
13    clippy::unnecessary_lazy_evaluations,
14    reason = "https://github.com/rust-lang/rust-clippy/issues/8109"
15)]
16#![cfg_attr(
17    test,
18    allow(clippy::non_ascii_literal, reason = "tests sometimes require UTF-8 string content")
19)]
20#![allow(unknown_lints)]
21#![warn(
22    missing_copy_implementations,
23    missing_debug_implementations,
24    missing_docs,
25    rust_2024_compatibility,
26    trivial_casts,
27    trivial_numeric_casts,
28    unused_qualifications,
29    variant_size_differences
30)]
31// Enable feature callouts in generated documentation:
32// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
33//
34// This approach is borrowed from tokio.
35#![cfg_attr(docsrs, feature(doc_cfg))]
36#![cfg_attr(docsrs, feature(doc_alias))]
37
38//! Contiguous growable vector types that implement the [Ruby `Array`] API.
39//!
40//! `Array` types are growable vectors with potentially heap-allocated contents.
41//! The types in this crate can be passed by pointer over FFI.
42//!
43//! `Array` types implement the mutating APIs in the Ruby `Array` core class as
44//! well as indexing and slicing APIs.
45//!
46//! `spinoso-array` is part of a [collection of crates] that implement the data
47//! structures that comprise the Ruby Core and Standard Library implementation
48//! for [Artichoke Ruby].
49//!
50//! # Array types
51//!
52//! - [`Array`] is based on [`Vec`] from the Rust `alloc` crate and standard
53//!   library. This Spinoso array type is enabled by default.
54#![cfg_attr(
55    feature = "small-array",
56    doc = "- [`SmallArray`] is based on [`SmallVec`] and implements the small vector"
57)]
58#![cfg_attr(
59    feature = "small-array",
60    doc = "  optimization – small arrays are stored inline without a heap allocation."
61)]
62#![cfg_attr(
63    feature = "small-array",
64    doc = "  This Spinoso array type requires the **small-array** Cargo feature."
65)]
66#![cfg_attr(
67    feature = "tiny-array",
68    doc = "- [`TinyArray`] is based on [`TinyVec`] and implements the small vector"
69)]
70#![cfg_attr(
71    feature = "tiny-array",
72    doc = "  optimization – small arrays are stored inline without a heap allocation."
73)]
74#![cfg_attr(
75    feature = "tiny-array",
76    doc = "  This Spinoso array type requires the **tiny-array** Cargo feature."
77)]
78//!
79//!
80//! # `no_std`
81//!
82//! This crate is `no_std` with a required dependency on the [`alloc`] crate.
83//!
84//! # Examples
85//!
86//! You can create an [`Array<T>`](Array) with [`new`](Array::new):
87//!
88//! ```
89//! # use spinoso_array::Array;
90//! let ary: Array<i32> = Array::new();
91//! ```
92//!
93//! Or with one of the many [`From`] and [`FromIterator`] implementations:
94//!
95//! ```
96//! # use core::iter;
97//! # use spinoso_array::Array;
98//! let ary: Array<i32> = Array::from(vec![1, 2, 3, 4]);
99//! let ary2: Array<i32> = iter::repeat_n(1, 10).collect();
100//! ```
101//!
102//! You can [`push`](Array::push) values onto the end of an array (which will
103//! grow the array as needed):
104//!
105//! ```
106//! # use spinoso_array::Array;
107//! let mut ary = Array::from(&[1, 2]);
108//! ary.push(3);
109//! ```
110//!
111//! Popping values behaves similarly:
112//!
113//! ```
114//! # use spinoso_array::Array;
115//! let mut ary = Array::from(&[1, 2]);
116//! assert_eq!(ary.pop(), Some(2));
117//! ```
118//!
119//! Arrays also support indexing (through the [`Index`] and [`IndexMut`]
120//! traits):
121//!
122//! ```
123//! # use spinoso_array::Array;
124//! let mut a = Array::from(&[1, 2, 3]);
125//! let three = a[2];
126//! a[1] = a[1] + 5;
127//! ```
128//!
129//! The `Array` vector types in this crate differ from [`Vec`] in the Rust `std`
130//! by offering many specialized slicing and mutation APIs. For example, rather
131//! than offering APIs like [`Vec::drain`] and [`Vec::splice`], array types in
132//! this crate offer specialized methods like [`shift`], [`shift_n`],
133//! [`unshift`], and [`unshift_n`] and `splice`-like methods with
134//! [`insert_slice`], and [`set_slice`].
135//!
136//! ```
137//! # use spinoso_array::Array;
138//! let mut a = Array::from(&[1, 2, 3]);
139//! a.unshift(0);
140//! assert_eq!(a, [0, 1, 2, 3]);
141//! let b = a.shift_n(10);
142//! assert_eq!(a, []);
143//! assert_eq!(b, [0, 1, 2, 3]);
144//! ```
145//!
146//! # Panics
147//!
148//! `Array`s in this crate do not expose panicking slicing operations (except for
149//! their [`Index`] and [`IndexMut`] implementations). Instead of panicking,
150//! slicing APIs operate until the end of the vector or return `&[]`. Mutating
151//! APIs extend `Array`s on out of bounds access.
152//!
153//! [Ruby `Array`]: https://ruby-doc.org/core-3.1.2/Array.html
154//! [collection of crates]: https://crates.io/keywords/spinoso
155//! [Artichoke Ruby]: https://www.artichokeruby.org/
156//! [`Vec`]: alloc::vec::Vec
157#![cfg_attr(feature = "small-array", doc = "[`SmallVec`]: smallvec::SmallVec")]
158#![cfg_attr(feature = "tiny-array", doc = "[`TinyVec`]: tinyvec::TinyVec")]
159//! [`From`]: core::convert::From
160//! [`FromIterator`]: core::iter::FromIterator
161//! [`Index`]: core::ops::Index
162//! [`IndexMut`]: core::ops::IndexMut
163//! [`Vec::drain`]: alloc::vec::Vec::drain
164//! [`Vec::splice`]: alloc::vec::Vec::splice
165//! [`shift`]: Array::shift
166//! [`shift_n`]: Array::shift_n
167//! [`unshift`]: Array::unshift
168//! [`unshift_n`]: Array::unshift_n
169//! [`insert_slice`]: Array::insert_slice
170//! [`set_slice`]: Array::set_slice
171
172// This crate is `no_std` + `alloc`
173#![no_std]
174
175// Ensure code blocks in `README.md` compile
176#[cfg(doctest)]
177#[doc = include_str!("../README.md")]
178mod readme {}
179
180extern crate alloc;
181
182mod array;
183
184#[cfg(any(feature = "small-array", feature = "tiny-array"))]
185pub use array::INLINE_CAPACITY;
186#[cfg(feature = "small-array")]
187pub use array::smallvec::SmallArray;
188#[cfg(feature = "tiny-array")]
189pub use array::tinyvec::TinyArray;
190pub use array::vec::{Array, RawParts};