diff options
Diffstat (limited to 'vendor/nonempty')
| -rw-r--r-- | vendor/nonempty/.cargo-checksum.json | 1 | ||||
| -rw-r--r-- | vendor/nonempty/Cargo.toml | 37 | ||||
| -rw-r--r-- | vendor/nonempty/LICENSE | 19 | ||||
| -rw-r--r-- | vendor/nonempty/README.md | 20 | ||||
| -rw-r--r-- | vendor/nonempty/deny.toml | 2 | ||||
| -rw-r--r-- | vendor/nonempty/flake.lock | 121 | ||||
| -rw-r--r-- | vendor/nonempty/flake.nix | 148 | ||||
| -rw-r--r-- | vendor/nonempty/src/lib.rs | 1206 | ||||
| -rw-r--r-- | vendor/nonempty/src/nonzero.rs | 96 |
9 files changed, 0 insertions, 1650 deletions
diff --git a/vendor/nonempty/.cargo-checksum.json b/vendor/nonempty/.cargo-checksum.json deleted file mode 100644 index 1c11e352..00000000 --- a/vendor/nonempty/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"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 deleted file mode 100644 index 835fc696..00000000 --- a/vendor/nonempty/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -# 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 deleted file mode 100644 index 1aa6bbcc..00000000 --- a/vendor/nonempty/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 0b18b605..00000000 --- a/vendor/nonempty/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# 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 deleted file mode 100644 index db2fc9e4..00000000 --- a/vendor/nonempty/deny.toml +++ /dev/null @@ -1,2 +0,0 @@ -[licenses] -allow = ["MIT"]
\ No newline at end of file diff --git a/vendor/nonempty/flake.lock b/vendor/nonempty/flake.lock deleted file mode 100644 index 3564b7de..00000000 --- a/vendor/nonempty/flake.lock +++ /dev/null @@ -1,121 +0,0 @@ -{ - "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 deleted file mode 100644 index 2b7b68f8..00000000 --- a/vendor/nonempty/flake.nix +++ /dev/null @@ -1,148 +0,0 @@ -{ - 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 deleted file mode 100644 index f95197c7..00000000 --- a/vendor/nonempty/src/lib.rs +++ /dev/null @@ -1,1206 +0,0 @@ -//! 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 deleted file mode 100644 index 4d611022..00000000 --- a/vendor/nonempty/src/nonzero.rs +++ /dev/null @@ -1,96 +0,0 @@ -#[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(()) - } - } -} |
