summaryrefslogtreecommitdiff
path: root/vendor/nonempty
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/nonempty
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/nonempty')
-rw-r--r--vendor/nonempty/.cargo-checksum.json1
-rw-r--r--vendor/nonempty/Cargo.toml37
-rw-r--r--vendor/nonempty/LICENSE19
-rw-r--r--vendor/nonempty/README.md20
-rw-r--r--vendor/nonempty/deny.toml2
-rw-r--r--vendor/nonempty/flake.lock121
-rw-r--r--vendor/nonempty/flake.nix148
-rw-r--r--vendor/nonempty/src/lib.rs1206
-rw-r--r--vendor/nonempty/src/nonzero.rs96
9 files changed, 1650 insertions, 0 deletions
diff --git a/vendor/nonempty/.cargo-checksum.json b/vendor/nonempty/.cargo-checksum.json
new file mode 100644
index 00000000..1c11e352
--- /dev/null
+++ b/vendor/nonempty/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"e7395e0be8efd51c690a0d0b48c3c1588f6b31bb90af1e46f307e64bd44f74a2","LICENSE":"e9a7f23bee03fd95309a52a27f3eb77ad8ba9910ec47871111dd80db4df41648","README.md":"04b9e1aa85725bd19b088595885149e1fc249b6fed9dc9bdc5ed3466b9a0b2ee","deny.toml":"468c8206f07be015dcf4d35e88395f4552708180705446dc3b687086440eb7c0","flake.lock":"16205cfef4a3c69bce077ad2e956a32a24e324a339e7ba37983229923a5d59af","flake.nix":"ed174d59ea9fd7b9f2a676bc35dc8fc513fd81e9b93487d7bf70963ce1ed9576","src/lib.rs":"9c89d6ec56614b68c14d9e7ea8de46d1b01644b937461d375e6fd04774f3ad27","src/nonzero.rs":"7b60a1032aa1e85248bdbee1ab2e23fec22c5cb8178a7d0396a5b15836b25981"},"package":"303e8749c804ccd6ca3b428de7fe0d86cb86bc7606bc15291f100fd487960bb8"} \ No newline at end of file
diff --git a/vendor/nonempty/Cargo.toml b/vendor/nonempty/Cargo.toml
new file mode 100644
index 00000000..835fc696
--- /dev/null
+++ b/vendor/nonempty/Cargo.toml
@@ -0,0 +1,37 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "nonempty"
+version = "0.10.0"
+authors = ["Alexis Sellier <self@cloudhead.io>"]
+description = "Correct by construction non-empty vector"
+readme = "README.md"
+license = "MIT"
+repository = "https://github.com/cloudhead/nonempty"
+
+[dependencies.arbitrary]
+version = "1"
+features = ["derive"]
+optional = true
+
+[dependencies.serde]
+version = "1"
+features = ["serde_derive"]
+optional = true
+
+[dev-dependencies.serde_json]
+version = "1"
+
+[features]
+arbitrary = ["dep:arbitrary"]
+serialize = ["serde"]
diff --git a/vendor/nonempty/LICENSE b/vendor/nonempty/LICENSE
new file mode 100644
index 00000000..1aa6bbcc
--- /dev/null
+++ b/vendor/nonempty/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2019 Alexis Sellier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/nonempty/README.md b/vendor/nonempty/README.md
new file mode 100644
index 00000000..0b18b605
--- /dev/null
+++ b/vendor/nonempty/README.md
@@ -0,0 +1,20 @@
+# Correct by Construction Non-Empty List
+
+This package exposes a type `NonEmpty<T>` with a data representation
+that guarantees non-emptiness statically:
+
+ struct NonEmpty<T>(T, Vec<T>)
+
+The library is meant to have an interface similar to `std::vec::Vec`:
+
+ use nonempty::NonEmpty;
+
+ let mut l = NonEmpty::new(42);
+
+ assert_eq!(l.first(), &42);
+
+ l.push(36);
+ l.push(58);
+
+ let v: Vec<i32> = l.into();
+ assert_eq!(v, vec![42, 36, 58]);
diff --git a/vendor/nonempty/deny.toml b/vendor/nonempty/deny.toml
new file mode 100644
index 00000000..db2fc9e4
--- /dev/null
+++ b/vendor/nonempty/deny.toml
@@ -0,0 +1,2 @@
+[licenses]
+allow = ["MIT"] \ No newline at end of file
diff --git a/vendor/nonempty/flake.lock b/vendor/nonempty/flake.lock
new file mode 100644
index 00000000..3564b7de
--- /dev/null
+++ b/vendor/nonempty/flake.lock
@@ -0,0 +1,121 @@
+{
+ "nodes": {
+ "advisory-db": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1708645386,
+ "narHash": "sha256-OdK/fVWOpbMBsl37pSWawPqpk5sePqtu1lx1UM+7c9Q=",
+ "owner": "rustsec",
+ "repo": "advisory-db",
+ "rev": "feb54ac57e980ef6578f66b307cfb844869e5260",
+ "type": "github"
+ },
+ "original": {
+ "owner": "rustsec",
+ "repo": "advisory-db",
+ "type": "github"
+ }
+ },
+ "crane": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1708794349,
+ "narHash": "sha256-jX+B1VGHT0ruHHL5RwS8L21R6miBn4B6s9iVyUJsJJY=",
+ "owner": "ipetkov",
+ "repo": "crane",
+ "rev": "2c94ff9a6fbeb9f3ea0107f28688edbe9c81deaa",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ipetkov",
+ "repo": "crane",
+ "type": "github"
+ }
+ },
+ "fenix": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "rust-analyzer-src": []
+ },
+ "locked": {
+ "lastModified": 1708928609,
+ "narHash": "sha256-LcXC2NP/TzHMmJThZGG1e+7rht5HeuZK5WOirIDg+lU=",
+ "owner": "nix-community",
+ "repo": "fenix",
+ "rev": "e928fb6b5179ebd032c19afac5c461ccc0b6de55",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "fenix",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1705309234,
+ "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1708905176,
+ "narHash": "sha256-pphkt8iO8CV/TugI7bsPOvFzi5mRSifkEQiwqYBK28s=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "227a4c47bef2390a7925693c51489e84169b1957",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "release-23.11",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "advisory-db": "advisory-db",
+ "crane": "crane",
+ "fenix": "fenix",
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/nonempty/flake.nix b/vendor/nonempty/flake.nix
new file mode 100644
index 00000000..2b7b68f8
--- /dev/null
+++ b/vendor/nonempty/flake.nix
@@ -0,0 +1,148 @@
+{
+ description = "Build a cargo project";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/release-23.11";
+
+ crane = {
+ url = "github:ipetkov/crane";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
+ fenix = {
+ url = "github:nix-community/fenix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ inputs.rust-analyzer-src.follows = "";
+ };
+
+ flake-utils.url = "github:numtide/flake-utils";
+
+ advisory-db = {
+ url = "github:rustsec/advisory-db";
+ flake = false;
+ };
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ crane,
+ fenix,
+ flake-utils,
+ advisory-db,
+ ...
+ }:
+ flake-utils.lib.eachDefaultSystem (system: let
+ pname = "nonempty";
+ pkgs = nixpkgs.legacyPackages.${system};
+
+ inherit (pkgs) lib;
+
+ craneLib = crane.lib.${system};
+ src = craneLib.cleanCargoSource (craneLib.path ./.);
+
+ # Common arguments can be set here to avoid repeating them later
+ commonArgs = {
+ inherit src;
+ strictDeps = true;
+
+ buildInputs =
+ [
+ # Add additional build inputs here
+ ]
+ ++ lib.optionals pkgs.stdenv.isDarwin [
+ # Additional darwin specific inputs can be set here
+ pkgs.libiconv
+ ];
+ };
+
+ craneLibLLvmTools =
+ craneLib.overrideToolchain
+ (fenix.packages.${system}.complete.withComponents [
+ "cargo"
+ "llvm-tools"
+ "rustc"
+ ]);
+
+ # Build *just* the cargo dependencies, so we can reuse
+ # all of that work (e.g. via cachix) when running in CI
+ cargoArtifacts = craneLib.buildDepsOnly commonArgs;
+
+ # Build the actual crate itself, reusing the dependency
+ # artifacts from above.
+ nonempty = craneLib.buildPackage (commonArgs
+ // {
+ inherit cargoArtifacts;
+ doCheck = false;
+ });
+ in {
+ # Formatter
+ formatter = pkgs.alejandra;
+
+ checks = {
+ # Build the crate as part of `nix flake check` for convenience
+ inherit nonempty;
+
+ # Run clippy (and deny all warnings) on the crate source,
+ # again, resuing the dependency artifacts from above.
+ #
+ # Note that this is done as a separate derivation so that
+ # we can block the CI if there are issues here, but not
+ # prevent downstream consumers from building our crate by itself.
+ nonempty-clippy = craneLib.cargoClippy (commonArgs
+ // {
+ inherit cargoArtifacts;
+ cargoClippyExtraArgs = "--all-targets -- --deny warnings";
+ });
+
+ nonempty-doc = craneLib.cargoDoc (commonArgs
+ // {
+ inherit cargoArtifacts;
+ });
+
+ # Check formatting
+ nonempty-fmt = craneLib.cargoFmt {
+ inherit src;
+ };
+
+ # Audit dependencies
+ nonempty-audit = craneLib.cargoAudit {
+ inherit src advisory-db;
+ };
+
+ # Audit licenses
+ nonempty-deny = craneLib.cargoDeny {
+ inherit src;
+ };
+
+ # Run tests with cargo-nextest
+ nonempty-nextest = craneLib.cargoNextest (commonArgs
+ // {
+ inherit cargoArtifacts;
+ partitions = 1;
+ partitionType = "count";
+ });
+ };
+
+ packages =
+ {
+ default = nonempty;
+ }
+ // lib.optionalAttrs (!pkgs.stdenv.isDarwin) {
+ nonempty-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs
+ // {
+ inherit cargoArtifacts;
+ });
+ };
+
+ devShells.default = craneLib.devShell {
+ # Extra inputs can be added here; cargo and rustc are provided by default.
+ packages = [
+ pkgs.cargo-watch
+ pkgs.cargo-nextest
+ pkgs.ripgrep
+ pkgs.rust-analyzer
+ ];
+ };
+ });
+}
diff --git a/vendor/nonempty/src/lib.rs b/vendor/nonempty/src/lib.rs
new file mode 100644
index 00000000..f95197c7
--- /dev/null
+++ b/vendor/nonempty/src/lib.rs
@@ -0,0 +1,1206 @@
+//! A Non-empty growable vector.
+//!
+//! Non-emptiness can be a powerful guarantee. If your main use of `Vec` is as
+//! an `Iterator`, then you may not need to distinguish on emptiness. But there
+//! are indeed times when the `Vec` you receive as as function argument needs to
+//! be non-empty or your function can't proceed. Similarly, there are times when
+//! the `Vec` you return to a calling user needs to promise it actually contains
+//! something.
+//!
+//! With `NonEmpty`, you're freed from the boilerplate of constantly needing to
+//! check `is_empty()` or pattern matching before proceeding, or erroring if you
+//! can't. So overall, code, type signatures, and logic become cleaner.
+//!
+//! Consider that unlike `Vec`, [`NonEmpty::first`] and [`NonEmpty::last`] don't
+//! return in `Option`, they always succeed.
+//!
+//! # Examples
+//!
+//! The simplest way to construct a [`NonEmpty`] is via the [`nonempty`] macro:
+//!
+//! ```
+//! use nonempty::{NonEmpty, nonempty};
+//!
+//! let l: NonEmpty<u32> = nonempty![1, 2, 3];
+//! assert_eq!(l.head, 1);
+//! ```
+//!
+//! Unlike the familiar `vec!` macro, `nonempty!` requires at least one element:
+//!
+//! ```
+//! use nonempty::nonempty;
+//!
+//! let l = nonempty![1];
+//!
+//! // Doesn't compile!
+//! // let l = nonempty![];
+//! ```
+//!
+//! Like `Vec`, you can also construct a [`NonEmpty`] the old fashioned way with
+//! [`NonEmpty::new`] or its constructor:
+//!
+//! ```
+//! use nonempty::NonEmpty;
+//!
+//! let mut l = NonEmpty { head: 42, tail: vec![36, 58] };
+//! assert_eq!(l.head, 42);
+//!
+//! l.push(9001);
+//! assert_eq!(l.last(), &9001);
+//! ```
+//!
+//! And if necessary, you're free to convert to and from `Vec`:
+//!
+//! ```
+//! use nonempty::{NonEmpty, nonempty};
+//!
+//! let l: NonEmpty<u32> = nonempty![42, 36, 58, 9001];
+//! let v: Vec<u32> = l.into();
+//! assert_eq!(v, vec![42, 36, 58, 9001]);
+//!
+//! let u: Option<NonEmpty<u32>> = NonEmpty::from_vec(v);
+//! assert_eq!(Some(nonempty![42, 36, 58, 9001]), u);
+//! ```
+//!
+//! # Caveats
+//!
+//! Since `NonEmpty` must have a least one element, it is not possible to
+//! implement the `FromInterator` trait for it. We can't know, in general, if
+//! any given `Iterator` actually contains something.
+//!
+//! # Features
+//!
+//! * `serialize`: `serde` support.
+//! * `arbitrary`: `arbitrary` support.
+#[cfg(feature = "arbitrary")]
+use arbitrary::Arbitrary;
+#[cfg(feature = "serialize")]
+use serde::{
+ ser::{SerializeSeq, Serializer},
+ Deserialize, Serialize,
+};
+use std::mem;
+use std::{cmp::Ordering, num::NonZeroUsize};
+use std::{iter, vec};
+
+pub mod nonzero;
+
+/// Like the `vec!` macro, but enforces at least one argument. A nice short-hand
+/// for constructing [`NonEmpty`] values.
+///
+/// ```
+/// use nonempty::{NonEmpty, nonempty};
+///
+/// let v = nonempty![1, 2, 3];
+/// assert_eq!(v, NonEmpty { head: 1, tail: vec![2, 3] });
+///
+/// let v = nonempty![1];
+/// assert_eq!(v, NonEmpty { head: 1, tail: Vec::new() });
+///
+/// // Accepts trailing commas
+/// let v = nonempty![1,];
+/// assert_eq!(v, NonEmpty { head: 1, tail: Vec::new() });
+///
+/// // Doesn't compile!
+/// // let v = nonempty![];
+/// ```
+#[macro_export]
+macro_rules! nonempty {
+ ($h:expr, $( $x:expr ),* $(,)?) => {{
+ let tail = vec![$($x),*];
+ $crate::NonEmpty { head: $h, tail }
+ }};
+ ($h:expr) => {
+ $crate::NonEmpty {
+ head: $h,
+ tail: Vec::new(),
+ }
+ };
+}
+
+/// Non-empty vector.
+#[cfg_attr(feature = "serialize", derive(Deserialize))]
+#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
+#[cfg_attr(feature = "serialize", serde(try_from = "Vec<T>"))]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct NonEmpty<T> {
+ pub head: T,
+ pub tail: Vec<T>,
+}
+
+// Nb. `Serialize` is implemented manually, as serde's `into` container attribute
+// requires a `T: Clone` bound which we'd like to avoid.
+#[cfg(feature = "serialize")]
+impl<T> Serialize for NonEmpty<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut seq = serializer.serialize_seq(Some(self.len()))?;
+ for e in self {
+ seq.serialize_element(e)?;
+ }
+ seq.end()
+ }
+}
+
+pub struct Iter<'a, T> {
+ head: Option<&'a T>,
+ tail: &'a [T],
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(value) = self.head.take() {
+ Some(value)
+ } else if let Some((first, rest)) = self.tail.split_first() {
+ self.tail = rest;
+ Some(first)
+ } else {
+ None
+ }
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if let Some((last, rest)) = self.tail.split_last() {
+ self.tail = rest;
+ Some(last)
+ } else if let Some(first_value) = self.head.take() {
+ Some(first_value)
+ } else {
+ None
+ }
+ }
+}
+
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {
+ fn len(&self) -> usize {
+ self.tail.len() + self.head.map_or(0, |_| 1)
+ }
+}
+
+impl<'a, T> core::iter::FusedIterator for Iter<'a, T> {}
+
+impl<T> NonEmpty<T> {
+ /// Alias for [`NonEmpty::singleton`].
+ pub const fn new(e: T) -> Self {
+ Self::singleton(e)
+ }
+
+ /// Attempt to convert an iterator into a `NonEmpty` vector.
+ /// Returns `None` if the iterator was empty.
+ pub fn collect<I>(iter: I) -> Option<NonEmpty<T>>
+ where
+ I: IntoIterator<Item = T>,
+ {
+ let mut iter = iter.into_iter();
+ let head = iter.next()?;
+ Some(Self {
+ head,
+ tail: iter.collect(),
+ })
+ }
+
+ /// Create a new non-empty list with an initial element.
+ pub const fn singleton(head: T) -> Self {
+ NonEmpty {
+ head,
+ tail: Vec::new(),
+ }
+ }
+
+ /// Always returns false.
+ pub const fn is_empty(&self) -> bool {
+ false
+ }
+
+ /// Get the first element. Never fails.
+ pub const fn first(&self) -> &T {
+ &self.head
+ }
+
+ /// Get the mutable reference to the first element. Never fails.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::new(42);
+ /// let head = non_empty.first_mut();
+ /// *head += 1;
+ /// assert_eq!(non_empty.first(), &43);
+ ///
+ /// let mut non_empty = NonEmpty::from((1, vec![4, 2, 3]));
+ /// let head = non_empty.first_mut();
+ /// *head *= 42;
+ /// assert_eq!(non_empty.first(), &42);
+ /// ```
+ pub fn first_mut(&mut self) -> &mut T {
+ &mut self.head
+ }
+
+ /// Get the possibly-empty tail of the list.
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new(42);
+ /// assert_eq!(non_empty.tail(), &[]);
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![4, 2, 3]));
+ /// assert_eq!(non_empty.tail(), &[4, 2, 3]);
+ /// ```
+ pub fn tail(&self) -> &[T] {
+ &self.tail
+ }
+
+ /// Push an element to the end of the list.
+ pub fn push(&mut self, e: T) {
+ self.tail.push(e)
+ }
+
+ /// Pop an element from the end of the list.
+ pub fn pop(&mut self) -> Option<T> {
+ self.tail.pop()
+ }
+
+ /// Inserts an element at position index within the vector, shifting all elements after it to the right.
+ ///
+ /// # Panics
+ ///
+ /// Panics if index > len.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::from((1, vec![2, 3]));
+ /// non_empty.insert(1, 4);
+ /// assert_eq!(non_empty, NonEmpty::from((1, vec![4, 2, 3])));
+ /// non_empty.insert(4, 5);
+ /// assert_eq!(non_empty, NonEmpty::from((1, vec![4, 2, 3, 5])));
+ /// non_empty.insert(0, 42);
+ /// assert_eq!(non_empty, NonEmpty::from((42, vec![1, 4, 2, 3, 5])));
+ /// ```
+ pub fn insert(&mut self, index: usize, element: T) {
+ let len = self.len();
+ assert!(index <= len);
+
+ if index == 0 {
+ let head = mem::replace(&mut self.head, element);
+ self.tail.insert(0, head);
+ } else {
+ self.tail.insert(index - 1, element);
+ }
+ }
+
+ /// Get the length of the list.
+ pub fn len(&self) -> usize {
+ self.tail.len() + 1
+ }
+
+ /// Gets the length of the list as a NonZeroUsize.
+ pub fn len_nonzero(&self) -> NonZeroUsize {
+ unsafe { NonZeroUsize::new_unchecked(self.tail.len().saturating_add(1)) }
+ }
+
+ /// Get the capacity of the list.
+ pub fn capacity(&self) -> usize {
+ self.tail.capacity() + 1
+ }
+
+ /// Get the last element. Never fails.
+ pub fn last(&self) -> &T {
+ match self.tail.last() {
+ None => &self.head,
+ Some(e) => e,
+ }
+ }
+
+ /// Get the last element mutably.
+ pub fn last_mut(&mut self) -> &mut T {
+ match self.tail.last_mut() {
+ None => &mut self.head,
+ Some(e) => e,
+ }
+ }
+
+ /// Check whether an element is contained in the list.
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut l = NonEmpty::from((42, vec![36, 58]));
+ ///
+ /// assert!(l.contains(&42));
+ /// assert!(!l.contains(&101));
+ /// ```
+ pub fn contains(&self, x: &T) -> bool
+ where
+ T: PartialEq,
+ {
+ self.iter().any(|e| e == x)
+ }
+
+ /// Get an element by index.
+ pub fn get(&self, index: usize) -> Option<&T> {
+ if index == 0 {
+ Some(&self.head)
+ } else {
+ self.tail.get(index - 1)
+ }
+ }
+
+ /// Get an element by index, mutably.
+ pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
+ if index == 0 {
+ Some(&mut self.head)
+ } else {
+ self.tail.get_mut(index - 1)
+ }
+ }
+
+ /// Truncate the list to a certain size. Must be greater than `0`.
+ pub fn truncate(&mut self, len: usize) {
+ assert!(len >= 1);
+ self.tail.truncate(len - 1);
+ }
+
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut l = NonEmpty::from((42, vec![36, 58]));
+ ///
+ /// let mut l_iter = l.iter();
+ ///
+ /// assert_eq!(l_iter.len(), 3);
+ /// assert_eq!(l_iter.next(), Some(&42));
+ /// assert_eq!(l_iter.next(), Some(&36));
+ /// assert_eq!(l_iter.next(), Some(&58));
+ /// assert_eq!(l_iter.next(), None);
+ /// ```
+ pub fn iter(&self) -> Iter<T> {
+ Iter {
+ head: Some(&self.head),
+ tail: &self.tail,
+ }
+ }
+
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut l = NonEmpty::new(42);
+ /// l.push(36);
+ /// l.push(58);
+ ///
+ /// for i in l.iter_mut() {
+ /// *i *= 10;
+ /// }
+ ///
+ /// let mut l_iter = l.iter();
+ ///
+ /// assert_eq!(l_iter.next(), Some(&420));
+ /// assert_eq!(l_iter.next(), Some(&360));
+ /// assert_eq!(l_iter.next(), Some(&580));
+ /// assert_eq!(l_iter.next(), None);
+ /// ```
+ pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> + '_ {
+ iter::once(&mut self.head).chain(self.tail.iter_mut())
+ }
+
+ /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is `NonEmpty` before
+ /// proceeding with a computation. Using `from_slice` will give us a proof
+ /// that we have a `NonEmpty` in the `Some` branch, otherwise it allows
+ /// the caller to handle the `None` case.
+ ///
+ /// # Example Use
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty_vec = NonEmpty::from_slice(&[1, 2, 3, 4, 5]);
+ /// assert_eq!(non_empty_vec, Some(NonEmpty::from((1, vec![2, 3, 4, 5]))));
+ ///
+ /// let empty_vec: Option<NonEmpty<&u32>> = NonEmpty::from_slice(&[]);
+ /// assert!(empty_vec.is_none());
+ /// ```
+ pub fn from_slice(slice: &[T]) -> Option<NonEmpty<T>>
+ where
+ T: Clone,
+ {
+ slice.split_first().map(|(h, t)| NonEmpty {
+ head: h.clone(),
+ tail: t.into(),
+ })
+ }
+
+ /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is `NonEmpty` before
+ /// proceeding with a computation. Using `from_vec` will give us a proof
+ /// that we have a `NonEmpty` in the `Some` branch, otherwise it allows
+ /// the caller to handle the `None` case.
+ ///
+ /// This version will consume the `Vec` you pass in. If you would rather pass the data as a
+ /// slice then use `NonEmpty::from_slice`.
+ ///
+ /// # Example Use
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty_vec = NonEmpty::from_vec(vec![1, 2, 3, 4, 5]);
+ /// assert_eq!(non_empty_vec, Some(NonEmpty::from((1, vec![2, 3, 4, 5]))));
+ ///
+ /// let empty_vec: Option<NonEmpty<&u32>> = NonEmpty::from_vec(vec![]);
+ /// assert!(empty_vec.is_none());
+ /// ```
+ pub fn from_vec(mut vec: Vec<T>) -> Option<NonEmpty<T>> {
+ if vec.is_empty() {
+ None
+ } else {
+ let head = vec.remove(0);
+ Some(NonEmpty { head, tail: vec })
+ }
+ }
+
+ /// Deconstruct a `NonEmpty` into its head and tail.
+ /// This operation never fails since we are guranteed
+ /// to have a head element.
+ ///
+ /// # Example Use
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// // Guaranteed to have the head and we also get the tail.
+ /// assert_eq!(non_empty.split_first(), (&1, &[2, 3, 4, 5][..]));
+ ///
+ /// let non_empty = NonEmpty::new(1);
+ ///
+ /// // Guaranteed to have the head element.
+ /// assert_eq!(non_empty.split_first(), (&1, &[][..]));
+ /// ```
+ pub fn split_first(&self) -> (&T, &[T]) {
+ (&self.head, &self.tail)
+ }
+
+ /// Deconstruct a `NonEmpty` into its first, last, and
+ /// middle elements, in that order.
+ ///
+ /// If there is only one element then first == last.
+ ///
+ /// # Example Use
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// // Guaranteed to have the last element and the elements
+ /// // preceding it.
+ /// assert_eq!(non_empty.split(), (&1, &[2, 3, 4][..], &5));
+ ///
+ /// let non_empty = NonEmpty::new(1);
+ ///
+ /// // Guaranteed to have the last element.
+ /// assert_eq!(non_empty.split(), (&1, &[][..], &1));
+ /// ```
+ pub fn split(&self) -> (&T, &[T], &T) {
+ match self.tail.split_last() {
+ None => (&self.head, &[], &self.head),
+ Some((last, middle)) => (&self.head, middle, last),
+ }
+ }
+
+ /// Append a `Vec` to the tail of the `NonEmpty`.
+ ///
+ /// # Example Use
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::new(1);
+ /// let mut vec = vec![2, 3, 4, 5];
+ /// non_empty.append(&mut vec);
+ ///
+ /// let mut expected = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// assert_eq!(non_empty, expected);
+ /// ```
+ pub fn append(&mut self, other: &mut Vec<T>) {
+ self.tail.append(other)
+ }
+
+ /// A structure preserving `map`. This is useful for when
+ /// we wish to keep the `NonEmpty` structure guaranteeing
+ /// that there is at least one element. Otherwise, we can
+ /// use `nonempty.iter().map(f)`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// let squares = non_empty.map(|i| i * i);
+ ///
+ /// let expected = NonEmpty::from((1, vec![4, 9, 16, 25]));
+ ///
+ /// assert_eq!(squares, expected);
+ /// ```
+ pub fn map<U, F>(self, mut f: F) -> NonEmpty<U>
+ where
+ F: FnMut(T) -> U,
+ {
+ NonEmpty {
+ head: f(self.head),
+ tail: self.tail.into_iter().map(f).collect(),
+ }
+ }
+
+ /// A structure preserving, fallible mapping function.
+ pub fn try_map<E, U, F>(self, mut f: F) -> Result<NonEmpty<U>, E>
+ where
+ F: FnMut(T) -> Result<U, E>,
+ {
+ Ok(NonEmpty {
+ head: f(self.head)?,
+ tail: self.tail.into_iter().map(f).collect::<Result<_, _>>()?,
+ })
+ }
+
+ /// When we have a function that goes from some `T` to a `NonEmpty<U>`,
+ /// we may want to apply it to a `NonEmpty<T>` but keep the structure flat.
+ /// This is where `flat_map` shines.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// let windows = non_empty.flat_map(|i| {
+ /// let mut next = NonEmpty::new(i + 5);
+ /// next.push(i + 6);
+ /// next
+ /// });
+ ///
+ /// let expected = NonEmpty::from((6, vec![7, 7, 8, 8, 9, 9, 10, 10, 11]));
+ ///
+ /// assert_eq!(windows, expected);
+ /// ```
+ pub fn flat_map<U, F>(self, mut f: F) -> NonEmpty<U>
+ where
+ F: FnMut(T) -> NonEmpty<U>,
+ {
+ let mut heads = f(self.head);
+ let mut tails = self
+ .tail
+ .into_iter()
+ .flat_map(|t| f(t).into_iter())
+ .collect();
+ heads.append(&mut tails);
+ heads
+ }
+
+ /// Flatten nested `NonEmpty`s into a single one.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((
+ /// NonEmpty::from((1, vec![2, 3])),
+ /// vec![NonEmpty::from((4, vec![5]))],
+ /// ));
+ ///
+ /// let expected = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// assert_eq!(NonEmpty::flatten(non_empty), expected);
+ /// ```
+ pub fn flatten(full: NonEmpty<NonEmpty<T>>) -> Self {
+ full.flat_map(|n| n)
+ }
+
+ /// Binary searches this sorted non-empty vector for a given element.
+ ///
+ /// If the value is found then Result::Ok is returned, containing the index of the matching element.
+ /// If there are multiple matches, then any one of the matches could be returned.
+ ///
+ /// If the value is not found then Result::Err is returned, containing the index where a
+ /// matching element could be inserted while maintaining sorted order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));
+ /// assert_eq!(non_empty.binary_search(&0), Ok(0));
+ /// assert_eq!(non_empty.binary_search(&13), Ok(9));
+ /// assert_eq!(non_empty.binary_search(&4), Err(7));
+ /// assert_eq!(non_empty.binary_search(&100), Err(13));
+ /// let r = non_empty.binary_search(&1);
+ /// assert!(match r { Ok(1..=4) => true, _ => false, });
+ /// ```
+ ///
+ /// If you want to insert an item to a sorted non-empty vector, while maintaining sort order:
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let mut non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));
+ /// let num = 42;
+ /// let idx = non_empty.binary_search(&num).unwrap_or_else(|x| x);
+ /// non_empty.insert(idx, num);
+ /// assert_eq!(non_empty, NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55])));
+ /// ```
+ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
+ where
+ T: Ord,
+ {
+ self.binary_search_by(|p| p.cmp(x))
+ }
+
+ /// Binary searches this sorted non-empty with a comparator function.
+ ///
+ /// The comparator function should implement an order consistent with the sort order of the underlying slice,
+ /// returning an order code that indicates whether its argument is Less, Equal or Greater the desired target.
+ ///
+ /// If the value is found then Result::Ok is returned, containing the index of the matching element.
+ /// If there are multiple matches, then any one of the matches could be returned.
+ /// If the value is not found then Result::Err is returned, containing the index where a matching element could be
+ /// inserted while maintaining sorted order.
+ ///
+ /// # Examples
+ ///
+ /// Looks up a series of four elements. The first is found, with a uniquely determined
+ /// position; the second and third are not found; the fourth could match any position in [1,4].
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));
+ /// let seek = 0;
+ /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Ok(0));
+ /// let seek = 13;
+ /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+ /// let seek = 4;
+ /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+ /// let seek = 100;
+ /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+ /// let seek = 1;
+ /// let r = non_empty.binary_search_by(|probe| probe.cmp(&seek));
+ /// assert!(match r { Ok(1..=4) => true, _ => false, });
+ /// ```
+ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
+ where
+ F: FnMut(&'a T) -> Ordering,
+ {
+ match f(&self.head) {
+ Ordering::Equal => Ok(0),
+ Ordering::Greater => Err(0),
+ Ordering::Less => self
+ .tail
+ .binary_search_by(f)
+ .map(|index| index + 1)
+ .map_err(|index| index + 1),
+ }
+ }
+
+ /// Binary searches this sorted non-empty vector with a key extraction function.
+ ///
+ /// Assumes that the vector is sorted by the key.
+ ///
+ /// If the value is found then Result::Ok is returned, containing the index of the matching element. If there are multiple matches,
+ /// then any one of the matches could be returned. If the value is not found then Result::Err is returned,
+ /// containing the index where a matching element could be inserted while maintaining sorted order.
+ ///
+ /// # Examples
+ ///
+ /// Looks up a series of four elements in a non-empty vector of pairs sorted by their second elements.
+ /// The first is found, with a uniquely determined position; the second and third are not found;
+ /// the fourth could match any position in [1, 4].
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((
+ /// (0, 0),
+ /// vec![(2, 1), (4, 1), (5, 1), (3, 1),
+ /// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+ /// (1, 21), (2, 34), (4, 55)]
+ /// ));
+ ///
+ /// assert_eq!(non_empty.binary_search_by_key(&0, |&(a,b)| b), Ok(0));
+ /// assert_eq!(non_empty.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
+ /// assert_eq!(non_empty.binary_search_by_key(&4, |&(a,b)| b), Err(7));
+ /// assert_eq!(non_empty.binary_search_by_key(&100, |&(a,b)| b), Err(13));
+ /// let r = non_empty.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert!(match r { Ok(1..=4) => true, _ => false, });
+ /// ```
+ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
+ where
+ B: Ord,
+ F: FnMut(&'a T) -> B,
+ {
+ self.binary_search_by(|k| f(k).cmp(b))
+ }
+
+ /// Returns the maximum element in the non-empty vector.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new(42);
+ /// assert_eq!(non_empty.maximum(), &42);
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![-34, 42, 76, 4, 5]));
+ /// assert_eq!(non_empty.maximum(), &76);
+ /// ```
+ pub fn maximum(&self) -> &T
+ where
+ T: Ord,
+ {
+ self.maximum_by(|i, j| i.cmp(j))
+ }
+
+ /// Returns the minimum element in the non-empty vector.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new(42);
+ /// assert_eq!(non_empty.minimum(), &42);
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![-34, 42, 76, 4, 5]));
+ /// assert_eq!(non_empty.minimum(), &-34);
+ /// ```
+ pub fn minimum(&self) -> &T
+ where
+ T: Ord,
+ {
+ self.minimum_by(|i, j| i.cmp(j))
+ }
+
+ /// Returns the element that gives the maximum value with respect to the specified comparison function.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new((0, 42));
+ /// assert_eq!(non_empty.maximum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 42));
+ ///
+ /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)]));
+ /// assert_eq!(non_empty.maximum_by(|(k, _), (l, _)| k.cmp(l)), &(4, 42));
+ /// ```
+ pub fn maximum_by<'a, F>(&'a self, mut compare: F) -> &T
+ where
+ F: FnMut(&'a T, &'a T) -> Ordering,
+ {
+ let mut max = &self.head;
+ for i in self.tail.iter() {
+ max = match compare(max, i) {
+ Ordering::Equal => max,
+ Ordering::Less => i,
+ Ordering::Greater => max,
+ };
+ }
+ max
+ }
+
+ /// Returns the element that gives the minimum value with respect to the specified comparison function.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new((0, 42));
+ /// assert_eq!(non_empty.minimum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 42));
+ ///
+ /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)]));
+ /// assert_eq!(non_empty.minimum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 76));
+ /// ```
+ pub fn minimum_by<'a, F>(&'a self, mut compare: F) -> &T
+ where
+ F: FnMut(&'a T, &'a T) -> Ordering,
+ {
+ self.maximum_by(|a, b| compare(a, b).reverse())
+ }
+
+ /// Returns the element that gives the maximum value with respect to the specified function.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new((0, 42));
+ /// assert_eq!(non_empty.maximum_by_key(|(k, _)| k), &(0, 42));
+ ///
+ /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)]));
+ /// assert_eq!(non_empty.maximum_by_key(|(k, _)| k), &(4, 42));
+ /// assert_eq!(non_empty.maximum_by_key(|(k, _)| -k), &(0, 76));
+ /// ```
+ pub fn maximum_by_key<'a, U, F>(&'a self, mut f: F) -> &T
+ where
+ U: Ord,
+ F: FnMut(&'a T) -> U,
+ {
+ self.maximum_by(|i, j| f(i).cmp(&f(j)))
+ }
+
+ /// Returns the element that gives the minimum value with respect to the specified function.
+ ///
+ /// This will return the first item in the vector if the tail is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::new((0, 42));
+ /// assert_eq!(non_empty.minimum_by_key(|(k, _)| k), &(0, 42));
+ ///
+ /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)]));
+ /// assert_eq!(non_empty.minimum_by_key(|(k, _)| k), &(0, 76));
+ /// assert_eq!(non_empty.minimum_by_key(|(k, _)| -k), &(4, 42));
+ /// ```
+ pub fn minimum_by_key<'a, U, F>(&'a self, mut f: F) -> &T
+ where
+ U: Ord,
+ F: FnMut(&'a T) -> U,
+ {
+ self.minimum_by(|i, j| f(i).cmp(&f(j)))
+ }
+}
+
+impl<T: Default> Default for NonEmpty<T> {
+ fn default() -> Self {
+ Self::new(T::default())
+ }
+}
+
+impl<T> From<NonEmpty<T>> for Vec<T> {
+ /// Turns a non-empty list into a Vec.
+ fn from(nonempty: NonEmpty<T>) -> Vec<T> {
+ iter::once(nonempty.head).chain(nonempty.tail).collect()
+ }
+}
+
+impl<T> From<NonEmpty<T>> for (T, Vec<T>) {
+ /// Turns a non-empty list into a Vec.
+ fn from(nonempty: NonEmpty<T>) -> (T, Vec<T>) {
+ (nonempty.head, nonempty.tail)
+ }
+}
+
+impl<T> From<(T, Vec<T>)> for NonEmpty<T> {
+ /// Turns a pair of an element and a Vec into
+ /// a NonEmpty.
+ fn from((head, tail): (T, Vec<T>)) -> Self {
+ NonEmpty { head, tail }
+ }
+}
+
+impl<T> IntoIterator for NonEmpty<T> {
+ type Item = T;
+ type IntoIter = iter::Chain<iter::Once<T>, vec::IntoIter<Self::Item>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ iter::once(self.head).chain(self.tail)
+ }
+}
+
+impl<'a, T> IntoIterator for &'a NonEmpty<T> {
+ type Item = &'a T;
+ type IntoIter = iter::Chain<iter::Once<&'a T>, std::slice::Iter<'a, T>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ iter::once(&self.head).chain(self.tail.iter())
+ }
+}
+
+impl<T> std::ops::Index<usize> for NonEmpty<T> {
+ type Output = T;
+
+ /// ```
+ /// use nonempty::NonEmpty;
+ ///
+ /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ ///
+ /// assert_eq!(non_empty[0], 1);
+ /// assert_eq!(non_empty[1], 2);
+ /// assert_eq!(non_empty[3], 4);
+ /// ```
+ fn index(&self, index: usize) -> &T {
+ if index > 0 {
+ &self.tail[index - 1]
+ } else {
+ &self.head
+ }
+ }
+}
+
+impl<T> std::ops::IndexMut<usize> for NonEmpty<T> {
+ fn index_mut(&mut self, index: usize) -> &mut T {
+ if index > 0 {
+ &mut self.tail[index - 1]
+ } else {
+ &mut self.head
+ }
+ }
+}
+
+impl<A> Extend<A> for NonEmpty<A> {
+ fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
+ self.tail.extend(iter)
+ }
+}
+
+#[cfg(feature = "serialize")]
+pub mod serialize {
+ use std::{convert::TryFrom, fmt};
+
+ use super::NonEmpty;
+
+ #[derive(Debug)]
+ pub enum Error {
+ Empty,
+ }
+
+ impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::Empty => f.write_str(
+ "the vector provided was empty, NonEmpty needs at least one element",
+ ),
+ }
+ }
+ }
+
+ impl<T> TryFrom<Vec<T>> for NonEmpty<T> {
+ type Error = Error;
+
+ fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
+ NonEmpty::from_vec(vec).ok_or(Error::Empty)
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::NonEmpty;
+
+ #[test]
+ fn test_from_conversion() {
+ let result = NonEmpty::from((1, vec![2, 3, 4, 5]));
+ let expected = NonEmpty {
+ head: 1,
+ tail: vec![2, 3, 4, 5],
+ };
+ assert_eq!(result, expected);
+ }
+
+ #[test]
+ fn test_into_iter() {
+ let nonempty = NonEmpty::from((0, vec![1, 2, 3]));
+ for (i, n) in nonempty.into_iter().enumerate() {
+ assert_eq!(i as i32, n);
+ }
+ }
+
+ #[test]
+ fn test_iter_syntax() {
+ let nonempty = NonEmpty::from((0, vec![1, 2, 3]));
+ for n in &nonempty {
+ let _ = *n; // Prove that we're dealing with references.
+ }
+ for _ in nonempty {}
+ }
+
+ #[test]
+ fn test_iter_both_directions() {
+ let mut nonempty = NonEmpty::from((0, vec![1, 2, 3]));
+ assert_eq!(nonempty.iter().cloned().collect::<Vec<_>>(), [0, 1, 2, 3]);
+ assert_eq!(
+ nonempty.iter().rev().cloned().collect::<Vec<_>>(),
+ [3, 2, 1, 0]
+ );
+ assert_eq!(
+ nonempty.iter_mut().rev().collect::<Vec<_>>(),
+ [&mut 3, &mut 2, &mut 1, &mut 0]
+ );
+ }
+
+ #[test]
+ fn test_iter_both_directions_at_once() {
+ let nonempty = NonEmpty::from((0, vec![1, 2, 3]));
+ let mut i = nonempty.iter();
+ assert_eq!(i.next(), Some(&0));
+ assert_eq!(i.next_back(), Some(&3));
+ assert_eq!(i.next(), Some(&1));
+ assert_eq!(i.next_back(), Some(&2));
+ assert_eq!(i.next(), None);
+ assert_eq!(i.next_back(), None);
+ }
+
+ #[test]
+ fn test_mutate_head() {
+ let mut non_empty = NonEmpty::new(42);
+ non_empty.head += 1;
+ assert_eq!(non_empty.head, 43);
+
+ let mut non_empty = NonEmpty::from((1, vec![4, 2, 3]));
+ non_empty.head *= 42;
+ assert_eq!(non_empty.head, 42);
+ }
+
+ #[test]
+ fn test_to_nonempty() {
+ use std::iter::{empty, once};
+
+ assert_eq!(NonEmpty::<()>::collect(empty()), None);
+ assert_eq!(NonEmpty::<()>::collect(once(())), Some(NonEmpty::new(())));
+ assert_eq!(
+ NonEmpty::<u8>::collect(once(1).chain(once(2))),
+ Some(nonempty!(1, 2))
+ );
+ }
+
+ #[test]
+ fn test_try_map() {
+ assert_eq!(
+ nonempty!(1, 2, 3, 4).try_map(Ok::<_, String>),
+ Ok(nonempty!(1, 2, 3, 4))
+ );
+ assert_eq!(
+ nonempty!(1, 2, 3, 4).try_map(|i| if i % 2 == 0 { Ok(i) } else { Err("not even") }),
+ Err("not even")
+ );
+ }
+
+ #[test]
+ fn test_nontrivial_minimum_by_key() {
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ struct Position {
+ x: i32,
+ y: i32,
+ }
+ impl Position {
+ pub fn distance_squared(&self, other: Position) -> u32 {
+ let dx = self.x - other.x;
+ let dy = self.y - other.y;
+ (dx * dx + dy * dy) as u32
+ }
+ }
+ let positions = nonempty![
+ Position { x: 1, y: 1 },
+ Position { x: 0, y: 0 },
+ Position { x: 3, y: 4 }
+ ];
+ let target = Position { x: 1, y: 2 };
+ let closest = positions.minimum_by_key(|position| position.distance_squared(target));
+ assert_eq!(closest, &Position { x: 1, y: 1 });
+ }
+
+ #[cfg(feature = "serialize")]
+ mod serialize {
+ use crate::NonEmpty;
+ use serde::{Deserialize, Serialize};
+
+ #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
+ pub struct SimpleSerializable(pub i32);
+
+ #[test]
+ fn test_simple_round_trip() -> Result<(), Box<dyn std::error::Error>> {
+ // Given
+ let mut non_empty = NonEmpty::new(SimpleSerializable(42));
+ non_empty.push(SimpleSerializable(777));
+
+ // When
+ let res = serde_json::from_str::<'_, NonEmpty<SimpleSerializable>>(
+ &serde_json::to_string(&non_empty)?,
+ )?;
+
+ // Then
+ assert_eq!(res, non_empty);
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_serialization() -> Result<(), Box<dyn std::error::Error>> {
+ let ne = nonempty![1, 2, 3, 4, 5];
+ let ve = vec![1, 2, 3, 4, 5];
+
+ assert_eq!(serde_json::to_string(&ne)?, serde_json::to_string(&ve)?);
+
+ Ok(())
+ }
+ }
+
+ #[cfg(feature = "arbitrary")]
+ mod arbitrary {
+ use crate::NonEmpty;
+ use arbitrary::{Arbitrary, Unstructured};
+
+ #[test]
+ fn test_arbitrary_empty_tail() -> arbitrary::Result<()> {
+ let mut u = Unstructured::new(&[1, 2, 3, 4]);
+ let ne = NonEmpty::<i32>::arbitrary(&mut u)?;
+ assert!(!ne.is_empty());
+ assert_eq!(
+ ne,
+ NonEmpty {
+ head: 67305985,
+ tail: vec![],
+ }
+ );
+ Ok(())
+ }
+
+ #[test]
+ fn test_arbitrary_with_tail() -> arbitrary::Result<()> {
+ let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]);
+ let ne = NonEmpty::<i32>::arbitrary(&mut u)?;
+ assert!(!ne.is_empty());
+ assert_eq!(
+ ne,
+ NonEmpty {
+ head: 67305985,
+ tail: vec![526086],
+ }
+ );
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/nonempty/src/nonzero.rs b/vendor/nonempty/src/nonzero.rs
new file mode 100644
index 00000000..4d611022
--- /dev/null
+++ b/vendor/nonempty/src/nonzero.rs
@@ -0,0 +1,96 @@
+#[cfg(feature = "arbitrary")]
+use arbitrary::Arbitrary;
+use std::num::NonZeroUsize;
+
+/// A non-empty list which statically guarantees certain operations
+/// cannot return zero, using [`std::num::NonZeroUsize`].
+///
+/// *Experimental*
+///
+#[repr(transparent)]
+#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct NonEmpty<T>(super::NonEmpty<T>);
+
+impl<T> NonEmpty<T> {
+ /// Get the length of the list.
+ pub fn len(&self) -> NonZeroUsize {
+ unsafe { NonZeroUsize::new_unchecked(self.0.tail.len() + 1) }
+ }
+
+ /// Get the capacity of the list.
+ pub fn capacity(&self) -> NonZeroUsize {
+ unsafe { NonZeroUsize::new_unchecked(self.0.tail.capacity() + 1) }
+ }
+
+ /// Truncate the list to a certain size.
+ pub fn truncate(&mut self, len: NonZeroUsize) {
+ self.tail.truncate(usize::from(len) - 1);
+ }
+}
+
+impl<T> From<super::NonEmpty<T>> for NonEmpty<T> {
+ fn from(other: super::NonEmpty<T>) -> NonEmpty<T> {
+ NonEmpty(other)
+ }
+}
+
+impl<T> std::ops::Deref for NonEmpty<T> {
+ type Target = super::NonEmpty<T>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl<T> std::ops::DerefMut for NonEmpty<T> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::nonzero;
+ use crate::NonEmpty;
+
+ use std::convert::TryInto;
+
+ #[test]
+ fn test_nonzero() {
+ let nonempty: nonzero::NonEmpty<_> = NonEmpty::from((0, vec![1, 2, 3])).into();
+
+ assert_eq!(nonempty.len(), 4.try_into().unwrap());
+ assert_eq!(nonempty.capacity(), 4.try_into().unwrap());
+ }
+
+ #[cfg(feature = "arbitrary")]
+ mod arbitrary {
+ use crate::nonzero;
+ use arbitrary::{Arbitrary, Unstructured};
+
+ use std::convert::TryInto;
+
+ #[test]
+ fn test_nonzero_arbitrary_empty_tail() -> arbitrary::Result<()> {
+ let mut u = Unstructured::new(&[1, 2, 3, 4]);
+ let nonempty: nonzero::NonEmpty<_> = nonzero::NonEmpty::<i32>::arbitrary(&mut u)?;
+
+ assert_eq!(nonempty.len(), 1.try_into().unwrap());
+ assert_eq!(nonempty.capacity(), 1.try_into().unwrap());
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_nonzero_arbitrary_with_tail() -> arbitrary::Result<()> {
+ let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]);
+ let nonempty: nonzero::NonEmpty<_> = nonzero::NonEmpty::<i32>::arbitrary(&mut u)?;
+
+ assert_eq!(nonempty.len(), 2.try_into().unwrap());
+ assert_eq!(nonempty.capacity(), 5.try_into().unwrap());
+
+ Ok(())
+ }
+ }
+}