#![doc = ""]
#![cfg_attr(feature = "alloc", doc = "```rust")]
#![cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#![doc = "```"]
#![doc = ""]
#![cfg_attr(feature = "alloc", doc = "```rust")]
#![cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#![doc = "```"]
#![doc = ""]
#![cfg_attr(feature = "alloc", doc = "```rust")]
#![cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#![doc = "```"]
#![doc = ""]
#![cfg_attr(feature = "alloc", doc = "```rust")]
#![cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#![doc = "```"]
#![doc = ""]
#![cfg_attr(feature = "alloc", doc = "```rust")]
#![cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#![doc = "```"]
#![doc = ""]
#![cfg_attr(feature = "std", doc = "```rust")]
#![cfg_attr(not(feature = "std"), doc = "```rust,ignore")]
#![doc = "```"]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(
clippy::cast_lossless,
clippy::checked_conversions,
clippy::cloned_instead_of_copied,
clippy::explicit_into_iter_loop,
clippy::filter_map_next,
clippy::flat_map_option,
clippy::from_iter_instead_of_collect,
clippy::if_not_else,
clippy::manual_ok_or,
clippy::map_unwrap_or,
clippy::match_same_arms,
clippy::redundant_closure_for_method_calls,
clippy::redundant_else,
clippy::unreadable_literal,
clippy::unused_self
)]
#![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
mod safety;
mod schemars;
mod serde;
mod take;
pub mod array1;
pub mod array_vec1;
pub mod borrow1;
pub mod boxed1;
pub mod btree_map1;
pub mod btree_set1;
pub mod cmp;
pub mod except;
pub mod hash;
pub mod hash_set1;
pub mod heapless;
pub mod index_map1;
pub mod index_set1;
pub mod iter1;
pub mod rc1;
pub mod segment;
pub mod slice1;
pub mod small_vec1;
pub mod str1;
pub mod string1;
pub mod sync1;
pub mod vec1;
pub mod vec_deque1;
mod sealed {
use crate::Cardinality;
pub unsafe trait MaybeEmpty {
fn cardinality(&self) -> Option<Cardinality<(), ()>>;
}
unsafe impl<T> MaybeEmpty for &'_ T
where
T: MaybeEmpty + ?Sized,
{
fn cardinality(&self) -> Option<Cardinality<(), ()>> {
<T as MaybeEmpty>::cardinality(*self)
}
}
unsafe impl<T> MaybeEmpty for &'_ mut T
where
T: MaybeEmpty + ?Sized,
{
fn cardinality(&self) -> Option<Cardinality<(), ()>> {
<T as MaybeEmpty>::cardinality(*self)
}
}
}
use crate::sealed::*;
pub mod prelude {
pub use crate::array1::Array1;
#[cfg(feature = "std")]
pub use crate::except::ByKey as _;
#[cfg(feature = "indexmap")]
pub use crate::index_map1::OrOnlyEntryExt as _;
#[cfg(feature = "either")]
pub use crate::iter1::EitherExt as _;
pub use crate::iter1::{
Extend1, FromIterator1, IntoIterator1, IteratorExt as _, ThenIterator1,
};
#[cfg(feature = "rayon")]
pub use crate::iter1::{FromParallelIterator1, IntoParallelIterator1};
#[cfg(any(feature = "arrayvec", feature = "alloc"))]
pub use crate::segment::{ByRange, ByTail};
pub use crate::slice1::{Slice1, slice1};
pub use crate::str1::Str1;
#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
pub use crate::sync1::{
ArcSlice1Ext as _, ArcStr1Ext as _, WeakSlice1Ext as _, WeakStr1Ext as _,
};
#[cfg(feature = "alloc")]
pub use {
crate::borrow1::{CowSlice1Ext as _, CowStr1Ext as _},
crate::boxed1::{BoxedSlice1Ext as _, BoxedStr1Ext as _},
crate::btree_map1::OrOnlyEntryExt as _,
crate::rc1::{RcSlice1Ext as _, RcStr1Ext as _, WeakSlice1Ext as _, WeakStr1Ext as _},
crate::string1::String1,
crate::vec1::{Vec1, vec1},
};
}
#[cfg(feature = "alloc")]
use alloc::borrow::ToOwned;
use core::cmp::Ordering;
use core::error::Error;
use core::fmt::{self, Debug, Display, Formatter};
use core::mem;
use core::num::NonZeroUsize;
#[cfg(any(feature = "arrayvec", feature = "alloc"))]
pub use take::TakeIfMany;
const EMPTY_ERROR_MESSAGE: &str = "failed to construct non-empty collection: no items";
trait MaybeEmptyExt: MaybeEmpty {
fn map_non_empty<T, F>(self, f: F) -> Result<T, EmptyError<Self>>
where
Self: Sized,
F: FnOnce(Self) -> T;
fn is_empty(&self) -> bool;
}
impl<T> MaybeEmptyExt for T
where
T: MaybeEmpty,
{
fn map_non_empty<U, F>(self, f: F) -> Result<U, EmptyError<Self>>
where
Self: Sized,
F: FnOnce(Self) -> U,
{
if self.is_empty() {
Err(EmptyError::from_empty(self))
}
else {
Ok(f(self))
}
}
fn is_empty(&self) -> bool {
self.cardinality().is_none()
}
}
trait NonZeroExt<T> {
fn clamped(n: T) -> Self;
}
impl NonZeroExt<usize> for NonZeroUsize {
fn clamped(n: usize) -> Self {
NonZeroUsize::new(n).unwrap_or(NonZeroUsize::MIN)
}
}
trait FromMaybeEmpty<T>: Sized
where
T: MaybeEmpty + Sized,
{
fn try_from_maybe_empty(items: T) -> Result<Self, EmptyError<T>> {
items.map_non_empty(|items| {
unsafe { Self::from_maybe_empty_unchecked(items) }
})
}
unsafe fn from_maybe_empty_unchecked(items: T) -> Self;
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub struct EmptyError<T> {
items: T,
}
impl<T> EmptyError<T> {
fn from_empty(items: T) -> Self {
EmptyError { items }
}
pub fn into_empty(self) -> T {
self.items
}
pub fn take(self) -> (T, EmptyError<()>) {
(self.items, EmptyError::from_empty(()))
}
pub fn take_and_drop(self) -> EmptyError<()> {
EmptyError::from_empty(())
}
pub fn as_empty(&self) -> &T {
&self.items
}
}
impl<T> EmptyError<&'_ T> {
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn into_owning(self) -> EmptyError<T::Owned>
where
T: ToOwned,
{
EmptyError::from_empty(self.items.to_owned())
}
}
impl<T> Debug for EmptyError<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter.debug_struct("EmptyError").finish_non_exhaustive()
}
}
impl<T> Display for EmptyError<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
write!(formatter, "{EMPTY_ERROR_MESSAGE}")
}
}
impl<T> Error for EmptyError<T> {}
#[derive(Clone, Copy, Hash)]
#[repr(transparent)]
pub struct NonEmpty<T>
where
T: ?Sized,
{
items: T,
}
impl<T> NonEmpty<T>
where
T: Sized,
{
#[doc = ""]
#[cfg_attr(feature = "alloc", doc = "```rust")]
#[cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")]
#[doc = "```"]
pub fn and_then_try<F>(self, f: F) -> Result<Self, EmptyError<T>>
where
Self: TryFrom<T, Error = EmptyError<T>>,
F: FnOnce(&mut T),
{
let NonEmpty { mut items } = self;
f(&mut items);
<NonEmpty<T> as TryFrom<T>>::try_from(items)
}
}
#[cfg(any(feature = "alloc", feature = "arrayvec", feature = "heapless"))]
impl<T> NonEmpty<T>
where
T: MaybeEmpty + ?Sized,
{
fn cardinality(&self) -> Cardinality<(), ()> {
match self.items.cardinality() {
None => unsafe { safety::unreachable_maybe_unchecked() },
Some(cardinality) => cardinality,
}
}
#[cfg(feature = "alloc")]
fn as_cardinality_items_mut(&mut self) -> Cardinality<&mut T, &mut T> {
match self.cardinality() {
Cardinality::One(_) => Cardinality::One(&mut self.items),
Cardinality::Many(_) => Cardinality::Many(&mut self.items),
}
}
}
impl<T> AsRef<T> for NonEmpty<T>
where
T: ?Sized,
{
fn as_ref(&self) -> &T {
&self.items
}
}
impl<T> Eq for NonEmpty<T>
where
Self: PartialEq,
T: Eq + ?Sized,
{
}
impl<T> FromMaybeEmpty<T> for NonEmpty<T>
where
T: MaybeEmpty,
{
unsafe fn from_maybe_empty_unchecked(items: T) -> Self {
NonEmpty { items }
}
}
impl<'a, T> FromMaybeEmpty<&'a T> for &'a NonEmpty<T>
where
T: ?Sized,
&'a T: MaybeEmpty,
{
unsafe fn from_maybe_empty_unchecked(items: &'a T) -> Self {
unsafe { mem::transmute::<&'_ T, &'_ NonEmpty<T>>(items) }
}
}
impl<'a, T> FromMaybeEmpty<&'a mut T> for &'a mut NonEmpty<T>
where
T: ?Sized,
&'a mut T: MaybeEmpty,
{
unsafe fn from_maybe_empty_unchecked(items: &'a mut T) -> Self {
unsafe { mem::transmute::<&'_ mut T, &'_ mut NonEmpty<T>>(items) }
}
}
impl<T> Ord for NonEmpty<T>
where
Self: PartialOrd,
T: Ord + ?Sized,
{
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self.items, &other.items)
}
}
impl<T, U> PartialEq<NonEmpty<U>> for NonEmpty<T>
where
T: PartialEq<U> + ?Sized,
U: ?Sized,
{
fn eq(&self, other: &NonEmpty<U>) -> bool {
PartialEq::eq(&self.items, &other.items)
}
}
impl<T, U> PartialOrd<NonEmpty<U>> for NonEmpty<T>
where
T: PartialOrd<U> + ?Sized,
U: ?Sized,
{
fn partial_cmp(&self, other: &NonEmpty<U>) -> Option<Ordering> {
PartialOrd::partial_cmp(&self.items, &other.items)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Cardinality<O, M> {
One(O),
Many(M),
}
impl<O, M> Cardinality<O, M> {
pub fn one(self) -> Option<O> {
match self {
Cardinality::One(one) => Some(one),
_ => None,
}
}
pub fn many(self) -> Option<M> {
match self {
Cardinality::Many(many) => Some(many),
_ => None,
}
}
pub fn map_one<U, F>(self, f: F) -> Cardinality<U, M>
where
F: FnOnce(O) -> U,
{
match self {
Cardinality::One(one) => Cardinality::One(f(one)),
Cardinality::Many(many) => Cardinality::Many(many),
}
}
pub fn map_many<U, F>(self, f: F) -> Cardinality<O, U>
where
F: FnOnce(M) -> U,
{
match self {
Cardinality::One(one) => Cardinality::One(one),
Cardinality::Many(many) => Cardinality::Many(f(many)),
}
}
}
impl<T> Cardinality<T, T> {
pub fn map<U, F>(self, f: F) -> Cardinality<U, U>
where
F: FnOnce(T) -> U,
{
match self {
Cardinality::One(one) => Cardinality::One(f(one)),
Cardinality::Many(many) => Cardinality::Many(f(many)),
}
}
}
macro_rules! with_literals {
($f:ident$(,)?) => {};
($f:ident, [$($N:literal $(,)?)+]$(,)?) => {
$(
$f!($N);
)+
};
}
pub(crate) use with_literals;
macro_rules! with_tuples {
($f:ident, ($head:ident $(,)?) $(,)?) => {
$f!(($head,));
};
($f:ident, ($head:ident, $($tail:ident $(,)?)+) $(,)?) => {
$f!(($head, $($tail,)+));
$crate::with_tuples!($f, ($($tail,)+));
};
}
pub(crate) use with_tuples;
macro_rules! with_unzipped_tuples {
($f:ident, (($headX:ident, $headY:ident $(,)?) $(,)?) $(,)?) => {
$f!(($headX,), ($headY,));
};
(
$f:ident,
(($headX:ident, $headY:ident $(,)?), $(($tailX:ident, $tailY:ident $(,)?) $(,)?)+)
$(,)?
) => {
$f!(($headX, $($tailX,)+), ($headY, $($tailY,)+));
$crate::with_unzipped_tuples!($f, ($(($tailX, $tailY),)+));
};
}
pub(crate) use with_unzipped_tuples;
macro_rules! impl_partial_eq_for_non_empty {
(
[$(for $ritem:ident $(,)?)? in $rhs:ty]
==
[$(for $litem:ident $(,)?)? in $lhs:ty] $(,)?
) => {
impl<$($ritem,)? $($litem)?> ::core::cmp::PartialEq<$rhs> for $lhs
where
$($litem: ::core::cmp::PartialEq<$ritem>,)?
{
fn eq(&self, rhs: &$rhs) -> bool {
::core::cmp::PartialEq::eq(&self.items, &rhs.items)
}
}
};
(
[$(for $ritem:ident $(,const $rn:ident: usize)? $(,)?)? in $rhs:ty]
<=
[$(for $litem:ident $(,)?)? in $lhs:ty] $(,)?
) => {
impl<$($ritem,)? $($litem,)? $($(const $rn: usize)?)?> ::core::cmp::PartialEq<$rhs> for $lhs
where
$($litem: ::core::cmp::PartialEq<$ritem>,)?
{
fn eq(&self, rhs: &$rhs) -> bool {
::core::cmp::PartialEq::eq(&self.items, rhs)
}
}
};
(
[$(for $ritem:ident $(,)?)? in $rhs:ty]
=>
[$(for $litem:ident $(,const $ln:ident: usize)? $(,)?)? in $lhs:ty] $(,)?
) => {
impl<$($ritem,)? $($litem,)? $($(const $ln: usize)?)?> ::core::cmp::PartialEq<$rhs> for $lhs
$(where
$litem: ::core::cmp::PartialEq<$ritem>,)?
{
fn eq(&self, rhs: &$rhs) -> bool {
::core::cmp::PartialEq::eq(self, &rhs.items)
}
}
};
}
pub(crate) use impl_partial_eq_for_non_empty;
#[cfg(all(test, feature = "alloc"))]
pub mod harness {
pub trait KeyValueRef {
type Cloned;
fn cloned(&self) -> Self::Cloned;
}
impl<'a, K, V> KeyValueRef for (&'a K, &'a V)
where
K: Clone,
V: Clone,
{
type Cloned = (K, V);
fn cloned(&self) -> Self::Cloned {
(self.0.clone(), self.1.clone())
}
}
impl<'a, K, V> KeyValueRef for (&'a K, &'a mut V)
where
K: Clone,
V: Clone,
{
type Cloned = (K, V);
fn cloned(&self) -> Self::Cloned {
(self.0.clone(), self.1.clone())
}
}
}