├── .github └── workflows │ └── actions.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src ├── lib.rs └── nonzero.rs /.github/workflows/actions.yml: -------------------------------------------------------------------------------- 1 | name: Cargo 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | name: Build and test 12 | strategy: 13 | matrix: 14 | os: ['ubuntu-latest', 'macos-latest'] 15 | runs-on: ${{ matrix.os }} 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Build 19 | run: cargo build --verbose 20 | env: 21 | RUSTFLAGS: -D warnings 22 | - name: Run tests 23 | run: cargo test --all --verbose --features serialize,arbitrary 24 | no-std: 25 | name: no-std build and test 26 | strategy: 27 | matrix: 28 | os: ['ubuntu-latest', 'macos-latest'] 29 | runs-on: ${{ matrix.os }} 30 | steps: 31 | - uses: actions/checkout@v2 32 | - name: Build 33 | run: cargo build --verbose --no-default-features 34 | env: 35 | RUSTFLAGS: -D warnings 36 | - name: Run tests 37 | run: cargo test --all --verbose --no-default-features 38 | 39 | rustfmt_and_clippy: 40 | name: Check rustfmt style && run clippy 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v2 44 | - uses: actions-rs/toolchain@v1 45 | with: 46 | toolchain: stable 47 | profile: minimal 48 | components: clippy, rustfmt 49 | override: true 50 | - name: Cache cargo registry 51 | uses: actions/cache@v1 52 | with: 53 | path: ~/.cargo/registry 54 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 55 | - name: Run clippy 56 | uses: actions-rs/cargo@v1 57 | with: 58 | command: clippy 59 | args: --all --tests --features serialize,arbitrary 60 | env: 61 | RUSTFLAGS: -D warnings 62 | - name: Check formating 63 | uses: actions-rs/cargo@v1 64 | with: 65 | command: fmt 66 | args: --all -- --check 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | .idea 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this library will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this library adheres to Rust's notion of 6 | [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## 0.11.0 9 | 10 | ### Added 11 | - `std` feature flag; building with `--no-default-features` now enables `no_std` use. 12 | - `NonEmpty::sort` was added. 13 | - `NonEmpty::as_ref` added for converting a `&NonEmpty` to `NonEmpty<&T>`. 14 | 15 | ### Changed 16 | - MSRV is now 1.56 (this is a semver-breaking change). 17 | - `NonEmpty::split` now returns `Option<&T>` for last element. 18 | - `cargo clippy` and `cargo doc` failures are fixed. 19 | 20 | ## [Unreleased] 21 | 22 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nonempty" 3 | version = "0.11.0" 4 | description = "Correct by construction non-empty vector" 5 | authors = ["Alexis Sellier "] 6 | edition = "2021" 7 | license = "MIT" 8 | repository = "https://github.com/cloudhead/nonempty" 9 | 10 | [dependencies] 11 | serde = { features = ["derive", "alloc"], default-features = false, optional = true, version = "1" } 12 | arbitrary = { features = ["derive"], optional = true, version = "1" } 13 | bincode = { optional = true, version = "2.0.0-rc.3" } 14 | 15 | [features] 16 | default = ["std"] 17 | std = [] 18 | serialize = ["dep:serde"] 19 | arbitrary = ["dep:arbitrary"] 20 | bincode2 = ["dep:bincode"] 21 | 22 | [dev-dependencies] 23 | serde_json = "1" 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Alexis Sellier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Correct by Construction Non-Empty List 2 | 3 | This package exposes a type `NonEmpty` with a data representation 4 | that guarantees non-emptiness statically: 5 | 6 | struct NonEmpty(T, Vec) 7 | 8 | The library is meant to have an interface similar to `std::vec::Vec`: 9 | 10 | use nonempty::NonEmpty; 11 | 12 | let mut l = NonEmpty::new(42); 13 | 14 | assert_eq!(l.first(), &42); 15 | 16 | l.push(36); 17 | l.push(58); 18 | 19 | let v: Vec = l.into(); 20 | assert_eq!(v, vec![42, 36, 58]); 21 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A Non-empty growable vector. 2 | //! 3 | //! Non-emptiness can be a powerful guarantee. If your main use of `Vec` is as 4 | //! an `Iterator`, then you may not need to distinguish on emptiness. But there 5 | //! are indeed times when the `Vec` you receive as as function argument needs to 6 | //! be non-empty or your function can't proceed. Similarly, there are times when 7 | //! the `Vec` you return to a calling user needs to promise it actually contains 8 | //! something. 9 | //! 10 | //! With `NonEmpty`, you're freed from the boilerplate of constantly needing to 11 | //! check `is_empty()` or pattern matching before proceeding, or erroring if you 12 | //! can't. So overall, code, type signatures, and logic become cleaner. 13 | //! 14 | //! Consider that unlike `Vec`, [`NonEmpty::first`] and [`NonEmpty::last`] don't 15 | //! return in `Option`, they always succeed. 16 | //! 17 | //! # Examples 18 | //! 19 | //! The simplest way to construct a [`NonEmpty`] is via the [`nonempty`] macro: 20 | //! 21 | //! ``` 22 | //! # extern crate alloc; 23 | //! # use alloc::vec::Vec; 24 | //! use nonempty::{NonEmpty, nonempty}; 25 | //! 26 | //! let l: NonEmpty = nonempty![1, 2, 3]; 27 | //! assert_eq!(l.head, 1); 28 | //! ``` 29 | //! 30 | //! Unlike the familiar `vec!` macro, `nonempty!` requires at least one element: 31 | //! 32 | //! ``` 33 | //! # extern crate alloc; 34 | //! # use alloc::vec::Vec; 35 | //! use nonempty::nonempty; 36 | //! 37 | //! let l = nonempty![1]; 38 | //! 39 | //! // Doesn't compile! 40 | //! // let l = nonempty![]; 41 | //! ``` 42 | //! 43 | //! Like `Vec`, you can also construct a [`NonEmpty`] the old fashioned way with 44 | //! [`NonEmpty::new`] or its constructor: 45 | //! 46 | //! ``` 47 | //! # extern crate alloc; 48 | //! # use alloc::vec::Vec; 49 | //! use nonempty::NonEmpty; 50 | //! 51 | //! let mut l = NonEmpty { head: 42, tail: vec![36, 58] }; 52 | //! assert_eq!(l.head, 42); 53 | //! 54 | //! l.push(9001); 55 | //! assert_eq!(l.last(), &9001); 56 | //! ``` 57 | //! 58 | //! And if necessary, you're free to convert to and from `Vec`: 59 | //! 60 | //! ``` 61 | //! use nonempty::{NonEmpty, nonempty}; 62 | //! 63 | //! let l: NonEmpty = nonempty![42, 36, 58, 9001]; 64 | //! let v: Vec = l.into(); 65 | //! assert_eq!(v, vec![42, 36, 58, 9001]); 66 | //! 67 | //! let u: Option> = NonEmpty::from_vec(v); 68 | //! assert_eq!(Some(nonempty![42, 36, 58, 9001]), u); 69 | //! ``` 70 | //! 71 | //! # Caveats 72 | //! 73 | //! Since `NonEmpty` must have a least one element, it is not possible to 74 | //! implement the `FromIterator` trait for it. We can't know, in general, if 75 | //! any given `Iterator` actually contains something. 76 | 77 | #![no_std] 78 | 79 | //! # Features 80 | //! 81 | //! * `serialize`: `serde` support. 82 | //! * `arbitrary`: `arbitrary` support. 83 | //! * `bincode2`" `bincode@2.0.0-rc.3` support. 84 | #[cfg(feature = "arbitrary")] 85 | use arbitrary::Arbitrary; 86 | #[cfg(feature = "bincode2")] 87 | use bincode::{Decode, Encode}; 88 | #[cfg(feature = "serialize")] 89 | use serde::{ 90 | ser::{SerializeSeq, Serializer}, 91 | Deserialize, Serialize, 92 | }; 93 | 94 | use core::iter; 95 | use core::mem; 96 | use core::{cmp::Ordering, num::NonZeroUsize}; 97 | 98 | #[cfg(feature = "std")] 99 | extern crate std; 100 | 101 | #[cfg_attr(test, macro_use)] 102 | extern crate alloc; 103 | use alloc::vec::{self, Vec}; 104 | 105 | pub mod nonzero; 106 | 107 | /// Like the `vec!` macro, but enforces at least one argument. A nice short-hand 108 | /// for constructing [`NonEmpty`] values. 109 | /// 110 | /// ``` 111 | /// # extern crate alloc; 112 | /// # use alloc::vec::Vec; 113 | /// use nonempty::{NonEmpty, nonempty}; 114 | /// 115 | /// let v = nonempty![1, 2, 3]; 116 | /// assert_eq!(v, NonEmpty { head: 1, tail: vec![2, 3] }); 117 | /// 118 | /// let v = nonempty![1]; 119 | /// assert_eq!(v, NonEmpty { head: 1, tail: Vec::new() }); 120 | /// 121 | /// // Accepts trailing commas 122 | /// let v = nonempty![1,]; 123 | /// assert_eq!(v, NonEmpty { head: 1, tail: Vec::new() }); 124 | /// 125 | /// // Doesn't compile! 126 | /// // let v = nonempty![]; 127 | /// ``` 128 | #[macro_export] 129 | macro_rules! nonempty { 130 | ($h:expr, $( $x:expr ),* $(,)?) => {{ 131 | let tail = vec![$($x),*]; 132 | $crate::NonEmpty { head: $h, tail } 133 | }}; 134 | ($h:expr) => { 135 | $crate::NonEmpty { 136 | head: $h, 137 | tail: alloc::vec::Vec::new(), 138 | } 139 | }; 140 | } 141 | 142 | /// Non-empty vector. 143 | #[cfg_attr(feature = "serialize", derive(Deserialize))] 144 | #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] 145 | #[cfg_attr(feature = "bincode2", derive(Encode, Decode))] 146 | #[cfg_attr(feature = "serialize", serde(try_from = "Vec"))] 147 | #[cfg_attr( 148 | feature = "bincode2", 149 | bincode( 150 | encode_bounds = "T: Encode + 'static", 151 | decode_bounds = "T: Decode + 'static", 152 | ) 153 | )] 154 | #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 155 | pub struct NonEmpty { 156 | pub head: T, 157 | pub tail: Vec, 158 | } 159 | 160 | // Nb. `Serialize` is implemented manually, as serde's `into` container attribute 161 | // requires a `T: Clone` bound which we'd like to avoid. 162 | #[cfg(feature = "serialize")] 163 | impl Serialize for NonEmpty 164 | where 165 | T: Serialize, 166 | { 167 | fn serialize(&self, serializer: S) -> Result 168 | where 169 | S: Serializer, 170 | { 171 | let mut seq = serializer.serialize_seq(Some(self.len()))?; 172 | for e in self { 173 | seq.serialize_element(e)?; 174 | } 175 | seq.end() 176 | } 177 | } 178 | 179 | pub struct Iter<'a, T> { 180 | head: Option<&'a T>, 181 | tail: &'a [T], 182 | } 183 | 184 | impl<'a, T> Iterator for Iter<'a, T> { 185 | type Item = &'a T; 186 | 187 | fn next(&mut self) -> Option { 188 | if let Some(value) = self.head.take() { 189 | Some(value) 190 | } else if let Some((first, rest)) = self.tail.split_first() { 191 | self.tail = rest; 192 | Some(first) 193 | } else { 194 | None 195 | } 196 | } 197 | } 198 | 199 | impl DoubleEndedIterator for Iter<'_, T> { 200 | fn next_back(&mut self) -> Option { 201 | if let Some((last, rest)) = self.tail.split_last() { 202 | self.tail = rest; 203 | Some(last) 204 | } else if let Some(first_value) = self.head.take() { 205 | Some(first_value) 206 | } else { 207 | None 208 | } 209 | } 210 | } 211 | 212 | impl ExactSizeIterator for Iter<'_, T> { 213 | fn len(&self) -> usize { 214 | self.tail.len() + self.head.map_or(0, |_| 1) 215 | } 216 | } 217 | 218 | impl core::iter::FusedIterator for Iter<'_, T> {} 219 | 220 | impl NonEmpty { 221 | /// Alias for [`NonEmpty::singleton`]. 222 | pub const fn new(e: T) -> Self { 223 | Self::singleton(e) 224 | } 225 | 226 | /// Converts from `&NonEmpty` to `NonEmpty<&T>`. 227 | pub fn as_ref(&self) -> NonEmpty<&T> { 228 | NonEmpty { 229 | head: &self.head, 230 | tail: self.tail.iter().collect(), 231 | } 232 | } 233 | 234 | /// Attempt to convert an iterator into a `NonEmpty` vector. 235 | /// Returns `None` if the iterator was empty. 236 | pub fn collect(iter: I) -> Option> 237 | where 238 | I: IntoIterator, 239 | { 240 | let mut iter = iter.into_iter(); 241 | let head = iter.next()?; 242 | Some(Self { 243 | head, 244 | tail: iter.collect(), 245 | }) 246 | } 247 | 248 | /// Create a new non-empty list with an initial element. 249 | pub const fn singleton(head: T) -> Self { 250 | NonEmpty { 251 | head, 252 | tail: Vec::new(), 253 | } 254 | } 255 | 256 | /// Always returns false. 257 | pub const fn is_empty(&self) -> bool { 258 | false 259 | } 260 | 261 | /// Get the first element. Never fails. 262 | pub const fn first(&self) -> &T { 263 | &self.head 264 | } 265 | 266 | /// Get the mutable reference to the first element. Never fails. 267 | /// 268 | /// # Examples 269 | /// 270 | /// ``` 271 | /// use nonempty::NonEmpty; 272 | /// 273 | /// let mut non_empty = NonEmpty::new(42); 274 | /// let head = non_empty.first_mut(); 275 | /// *head += 1; 276 | /// assert_eq!(non_empty.first(), &43); 277 | /// 278 | /// let mut non_empty = NonEmpty::from((1, vec![4, 2, 3])); 279 | /// let head = non_empty.first_mut(); 280 | /// *head *= 42; 281 | /// assert_eq!(non_empty.first(), &42); 282 | /// ``` 283 | pub fn first_mut(&mut self) -> &mut T { 284 | &mut self.head 285 | } 286 | 287 | /// Get the possibly-empty tail of the list. 288 | /// 289 | /// ``` 290 | /// use nonempty::NonEmpty; 291 | /// 292 | /// let non_empty = NonEmpty::new(42); 293 | /// assert_eq!(non_empty.tail(), &[]); 294 | /// 295 | /// let non_empty = NonEmpty::from((1, vec![4, 2, 3])); 296 | /// assert_eq!(non_empty.tail(), &[4, 2, 3]); 297 | /// ``` 298 | pub fn tail(&self) -> &[T] { 299 | &self.tail 300 | } 301 | 302 | /// Push an element to the end of the list. 303 | pub fn push(&mut self, e: T) { 304 | self.tail.push(e) 305 | } 306 | 307 | /// Pop an element from the end of the list. 308 | pub fn pop(&mut self) -> Option { 309 | self.tail.pop() 310 | } 311 | 312 | /// Inserts an element at position index within the vector, shifting all elements after it to the right. 313 | /// 314 | /// # Panics 315 | /// 316 | /// Panics if index > len. 317 | /// 318 | /// # Examples 319 | /// 320 | /// ``` 321 | /// use nonempty::NonEmpty; 322 | /// 323 | /// let mut non_empty = NonEmpty::from((1, vec![2, 3])); 324 | /// non_empty.insert(1, 4); 325 | /// assert_eq!(non_empty, NonEmpty::from((1, vec![4, 2, 3]))); 326 | /// non_empty.insert(4, 5); 327 | /// assert_eq!(non_empty, NonEmpty::from((1, vec![4, 2, 3, 5]))); 328 | /// non_empty.insert(0, 42); 329 | /// assert_eq!(non_empty, NonEmpty::from((42, vec![1, 4, 2, 3, 5]))); 330 | /// ``` 331 | pub fn insert(&mut self, index: usize, element: T) { 332 | let len = self.len(); 333 | assert!(index <= len); 334 | 335 | if index == 0 { 336 | let head = mem::replace(&mut self.head, element); 337 | self.tail.insert(0, head); 338 | } else { 339 | self.tail.insert(index - 1, element); 340 | } 341 | } 342 | 343 | /// Get the length of the list. 344 | pub fn len(&self) -> usize { 345 | self.tail.len() + 1 346 | } 347 | 348 | /// Gets the length of the list as a NonZeroUsize. 349 | pub fn len_nonzero(&self) -> NonZeroUsize { 350 | unsafe { NonZeroUsize::new_unchecked(self.tail.len().saturating_add(1)) } 351 | } 352 | 353 | /// Get the capacity of the list. 354 | pub fn capacity(&self) -> usize { 355 | self.tail.capacity() + 1 356 | } 357 | 358 | /// Get the last element. Never fails. 359 | pub fn last(&self) -> &T { 360 | match self.tail.last() { 361 | None => &self.head, 362 | Some(e) => e, 363 | } 364 | } 365 | 366 | /// Get the last element mutably. 367 | pub fn last_mut(&mut self) -> &mut T { 368 | match self.tail.last_mut() { 369 | None => &mut self.head, 370 | Some(e) => e, 371 | } 372 | } 373 | 374 | /// Check whether an element is contained in the list. 375 | /// 376 | /// ``` 377 | /// use nonempty::NonEmpty; 378 | /// 379 | /// let mut l = NonEmpty::from((42, vec![36, 58])); 380 | /// 381 | /// assert!(l.contains(&42)); 382 | /// assert!(!l.contains(&101)); 383 | /// ``` 384 | pub fn contains(&self, x: &T) -> bool 385 | where 386 | T: PartialEq, 387 | { 388 | self.iter().any(|e| e == x) 389 | } 390 | 391 | /// Get an element by index. 392 | pub fn get(&self, index: usize) -> Option<&T> { 393 | if index == 0 { 394 | Some(&self.head) 395 | } else { 396 | self.tail.get(index - 1) 397 | } 398 | } 399 | 400 | /// Get an element by index, mutably. 401 | pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { 402 | if index == 0 { 403 | Some(&mut self.head) 404 | } else { 405 | self.tail.get_mut(index - 1) 406 | } 407 | } 408 | 409 | /// Truncate the list to a certain size. Must be greater than `0`. 410 | pub fn truncate(&mut self, len: usize) { 411 | assert!(len >= 1); 412 | self.tail.truncate(len - 1); 413 | } 414 | 415 | /// ``` 416 | /// use nonempty::NonEmpty; 417 | /// 418 | /// let mut l = NonEmpty::from((42, vec![36, 58])); 419 | /// 420 | /// let mut l_iter = l.iter(); 421 | /// 422 | /// assert_eq!(l_iter.len(), 3); 423 | /// assert_eq!(l_iter.next(), Some(&42)); 424 | /// assert_eq!(l_iter.next(), Some(&36)); 425 | /// assert_eq!(l_iter.next(), Some(&58)); 426 | /// assert_eq!(l_iter.next(), None); 427 | /// ``` 428 | pub fn iter(&self) -> Iter { 429 | Iter { 430 | head: Some(&self.head), 431 | tail: &self.tail, 432 | } 433 | } 434 | 435 | /// ``` 436 | /// use nonempty::NonEmpty; 437 | /// 438 | /// let mut l = NonEmpty::new(42); 439 | /// l.push(36); 440 | /// l.push(58); 441 | /// 442 | /// for i in l.iter_mut() { 443 | /// *i *= 10; 444 | /// } 445 | /// 446 | /// let mut l_iter = l.iter(); 447 | /// 448 | /// assert_eq!(l_iter.next(), Some(&420)); 449 | /// assert_eq!(l_iter.next(), Some(&360)); 450 | /// assert_eq!(l_iter.next(), Some(&580)); 451 | /// assert_eq!(l_iter.next(), None); 452 | /// ``` 453 | pub fn iter_mut(&mut self) -> impl DoubleEndedIterator + '_ { 454 | iter::once(&mut self.head).chain(self.tail.iter_mut()) 455 | } 456 | 457 | /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is `NonEmpty` before 458 | /// proceeding with a computation. Using `from_slice` will give us a proof 459 | /// that we have a `NonEmpty` in the `Some` branch, otherwise it allows 460 | /// the caller to handle the `None` case. 461 | /// 462 | /// # Example Use 463 | /// 464 | /// ``` 465 | /// use nonempty::NonEmpty; 466 | /// 467 | /// let non_empty_vec = NonEmpty::from_slice(&[1, 2, 3, 4, 5]); 468 | /// assert_eq!(non_empty_vec, Some(NonEmpty::from((1, vec![2, 3, 4, 5])))); 469 | /// 470 | /// let empty_vec: Option> = NonEmpty::from_slice(&[]); 471 | /// assert!(empty_vec.is_none()); 472 | /// ``` 473 | pub fn from_slice(slice: &[T]) -> Option> 474 | where 475 | T: Clone, 476 | { 477 | slice.split_first().map(|(h, t)| NonEmpty { 478 | head: h.clone(), 479 | tail: t.into(), 480 | }) 481 | } 482 | 483 | /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is `NonEmpty` before 484 | /// proceeding with a computation. Using `from_vec` will give us a proof 485 | /// that we have a `NonEmpty` in the `Some` branch, otherwise it allows 486 | /// the caller to handle the `None` case. 487 | /// 488 | /// This version will consume the `Vec` you pass in. If you would rather pass the data as a 489 | /// slice then use `NonEmpty::from_slice`. 490 | /// 491 | /// # Example Use 492 | /// 493 | /// ``` 494 | /// use nonempty::NonEmpty; 495 | /// 496 | /// let non_empty_vec = NonEmpty::from_vec(vec![1, 2, 3, 4, 5]); 497 | /// assert_eq!(non_empty_vec, Some(NonEmpty::from((1, vec![2, 3, 4, 5])))); 498 | /// 499 | /// let empty_vec: Option> = NonEmpty::from_vec(vec![]); 500 | /// assert!(empty_vec.is_none()); 501 | /// ``` 502 | pub fn from_vec(mut vec: Vec) -> Option> { 503 | if vec.is_empty() { 504 | None 505 | } else { 506 | let head = vec.remove(0); 507 | Some(NonEmpty { head, tail: vec }) 508 | } 509 | } 510 | 511 | /// Deconstruct a `NonEmpty` into its head and tail. 512 | /// This operation never fails since we are guaranteed 513 | /// to have a head element. 514 | /// 515 | /// # Example Use 516 | /// 517 | /// ``` 518 | /// use nonempty::NonEmpty; 519 | /// 520 | /// let mut non_empty = NonEmpty::from((1, vec![2, 3, 4, 5])); 521 | /// 522 | /// // Guaranteed to have the head and we also get the tail. 523 | /// assert_eq!(non_empty.split_first(), (&1, &[2, 3, 4, 5][..])); 524 | /// 525 | /// let non_empty = NonEmpty::new(1); 526 | /// 527 | /// // Guaranteed to have the head element. 528 | /// assert_eq!(non_empty.split_first(), (&1, &[][..])); 529 | /// ``` 530 | pub fn split_first(&self) -> (&T, &[T]) { 531 | (&self.head, &self.tail) 532 | } 533 | 534 | /// Deconstruct a `NonEmpty` into its first, last, and 535 | /// middle elements, in that order. 536 | /// 537 | /// If there is only one element then last is `None`. 538 | /// 539 | /// # Example Use 540 | /// 541 | /// ``` 542 | /// use nonempty::NonEmpty; 543 | /// 544 | /// let mut non_empty = NonEmpty::from((1, vec![2, 3, 4, 5])); 545 | /// 546 | /// // When there are two or more elements, the last element is represented 547 | /// // as a `Some`. Elements preceding it, except for the first, are returned 548 | /// // in the middle. 549 | /// assert_eq!(non_empty.split(), (&1, &[2, 3, 4][..], Some(&5))); 550 | /// 551 | /// let non_empty = NonEmpty::new(1); 552 | /// 553 | /// // The last element is `None` when there's only one element. 554 | /// assert_eq!(non_empty.split(), (&1, &[][..], None)); 555 | /// ``` 556 | pub fn split(&self) -> (&T, &[T], Option<&T>) { 557 | match self.tail.split_last() { 558 | None => (&self.head, &[], None), 559 | Some((last, middle)) => (&self.head, middle, Some(last)), 560 | } 561 | } 562 | 563 | /// Append a `Vec` to the tail of the `NonEmpty`. 564 | /// 565 | /// # Example Use 566 | /// 567 | /// ``` 568 | /// use nonempty::NonEmpty; 569 | /// 570 | /// let mut non_empty = NonEmpty::new(1); 571 | /// let mut vec = vec![2, 3, 4, 5]; 572 | /// non_empty.append(&mut vec); 573 | /// 574 | /// let mut expected = NonEmpty::from((1, vec![2, 3, 4, 5])); 575 | /// 576 | /// assert_eq!(non_empty, expected); 577 | /// ``` 578 | pub fn append(&mut self, other: &mut Vec) { 579 | self.tail.append(other) 580 | } 581 | 582 | /// A structure preserving `map`. This is useful for when 583 | /// we wish to keep the `NonEmpty` structure guaranteeing 584 | /// that there is at least one element. Otherwise, we can 585 | /// use `nonempty.iter().map(f)`. 586 | /// 587 | /// # Examples 588 | /// 589 | /// ``` 590 | /// use nonempty::NonEmpty; 591 | /// 592 | /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5])); 593 | /// 594 | /// let squares = non_empty.map(|i| i * i); 595 | /// 596 | /// let expected = NonEmpty::from((1, vec![4, 9, 16, 25])); 597 | /// 598 | /// assert_eq!(squares, expected); 599 | /// ``` 600 | pub fn map(self, mut f: F) -> NonEmpty 601 | where 602 | F: FnMut(T) -> U, 603 | { 604 | NonEmpty { 605 | head: f(self.head), 606 | tail: self.tail.into_iter().map(f).collect(), 607 | } 608 | } 609 | 610 | /// A structure preserving, fallible mapping function. 611 | pub fn try_map(self, mut f: F) -> Result, E> 612 | where 613 | F: FnMut(T) -> Result, 614 | { 615 | Ok(NonEmpty { 616 | head: f(self.head)?, 617 | tail: self.tail.into_iter().map(f).collect::>()?, 618 | }) 619 | } 620 | 621 | /// When we have a function that goes from some `T` to a `NonEmpty`, 622 | /// we may want to apply it to a `NonEmpty` but keep the structure flat. 623 | /// This is where `flat_map` shines. 624 | /// 625 | /// # Examples 626 | /// 627 | /// ``` 628 | /// use nonempty::NonEmpty; 629 | /// 630 | /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5])); 631 | /// 632 | /// let windows = non_empty.flat_map(|i| { 633 | /// let mut next = NonEmpty::new(i + 5); 634 | /// next.push(i + 6); 635 | /// next 636 | /// }); 637 | /// 638 | /// let expected = NonEmpty::from((6, vec![7, 7, 8, 8, 9, 9, 10, 10, 11])); 639 | /// 640 | /// assert_eq!(windows, expected); 641 | /// ``` 642 | pub fn flat_map(self, mut f: F) -> NonEmpty 643 | where 644 | F: FnMut(T) -> NonEmpty, 645 | { 646 | let mut heads = f(self.head); 647 | let mut tails = self 648 | .tail 649 | .into_iter() 650 | .flat_map(|t| f(t).into_iter()) 651 | .collect(); 652 | heads.append(&mut tails); 653 | heads 654 | } 655 | 656 | /// Flatten nested `NonEmpty`s into a single one. 657 | /// 658 | /// # Examples 659 | /// 660 | /// ``` 661 | /// use nonempty::NonEmpty; 662 | /// 663 | /// let non_empty = NonEmpty::from(( 664 | /// NonEmpty::from((1, vec![2, 3])), 665 | /// vec![NonEmpty::from((4, vec![5]))], 666 | /// )); 667 | /// 668 | /// let expected = NonEmpty::from((1, vec![2, 3, 4, 5])); 669 | /// 670 | /// assert_eq!(NonEmpty::flatten(non_empty), expected); 671 | /// ``` 672 | pub fn flatten(full: NonEmpty>) -> Self { 673 | full.flat_map(|n| n) 674 | } 675 | 676 | /// Binary searches this sorted non-empty vector for a given element. 677 | /// 678 | /// If the value is found then Result::Ok is returned, containing the index of the matching element. 679 | /// If there are multiple matches, then any one of the matches could be returned. 680 | /// 681 | /// If the value is not found then Result::Err is returned, containing the index where a 682 | /// matching element could be inserted while maintaining sorted order. 683 | /// 684 | /// # Examples 685 | /// 686 | /// ``` 687 | /// use nonempty::NonEmpty; 688 | /// 689 | /// let non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])); 690 | /// assert_eq!(non_empty.binary_search(&0), Ok(0)); 691 | /// assert_eq!(non_empty.binary_search(&13), Ok(9)); 692 | /// assert_eq!(non_empty.binary_search(&4), Err(7)); 693 | /// assert_eq!(non_empty.binary_search(&100), Err(13)); 694 | /// let r = non_empty.binary_search(&1); 695 | /// assert!(match r { Ok(1..=4) => true, _ => false, }); 696 | /// ``` 697 | /// 698 | /// If you want to insert an item to a sorted non-empty vector, while maintaining sort order: 699 | /// 700 | /// ``` 701 | /// use nonempty::NonEmpty; 702 | /// 703 | /// let mut non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])); 704 | /// let num = 42; 705 | /// let idx = non_empty.binary_search(&num).unwrap_or_else(|x| x); 706 | /// non_empty.insert(idx, num); 707 | /// assert_eq!(non_empty, NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]))); 708 | /// ``` 709 | pub fn binary_search(&self, x: &T) -> Result 710 | where 711 | T: Ord, 712 | { 713 | self.binary_search_by(|p| p.cmp(x)) 714 | } 715 | 716 | /// Binary searches this sorted non-empty with a comparator function. 717 | /// 718 | /// The comparator function should implement an order consistent with the sort order of the underlying slice, 719 | /// returning an order code that indicates whether its argument is Less, Equal or Greater the desired target. 720 | /// 721 | /// If the value is found then Result::Ok is returned, containing the index of the matching element. 722 | /// If there are multiple matches, then any one of the matches could be returned. 723 | /// If the value is not found then Result::Err is returned, containing the index where a matching element could be 724 | /// inserted while maintaining sorted order. 725 | /// 726 | /// # Examples 727 | /// 728 | /// Looks up a series of four elements. The first is found, with a uniquely determined 729 | /// position; the second and third are not found; the fourth could match any position in `[1,4]`. 730 | /// 731 | /// ``` 732 | /// use nonempty::NonEmpty; 733 | /// 734 | /// let non_empty = NonEmpty::from((0, vec![1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])); 735 | /// let seek = 0; 736 | /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Ok(0)); 737 | /// let seek = 13; 738 | /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Ok(9)); 739 | /// let seek = 4; 740 | /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Err(7)); 741 | /// let seek = 100; 742 | /// assert_eq!(non_empty.binary_search_by(|probe| probe.cmp(&seek)), Err(13)); 743 | /// let seek = 1; 744 | /// let r = non_empty.binary_search_by(|probe| probe.cmp(&seek)); 745 | /// assert!(match r { Ok(1..=4) => true, _ => false, }); 746 | /// ``` 747 | pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result 748 | where 749 | F: FnMut(&'a T) -> Ordering, 750 | { 751 | match f(&self.head) { 752 | Ordering::Equal => Ok(0), 753 | Ordering::Greater => Err(0), 754 | Ordering::Less => self 755 | .tail 756 | .binary_search_by(f) 757 | .map(|index| index + 1) 758 | .map_err(|index| index + 1), 759 | } 760 | } 761 | 762 | /// Binary searches this sorted non-empty vector with a key extraction function. 763 | /// 764 | /// Assumes that the vector is sorted by the key. 765 | /// 766 | /// If the value is found then Result::Ok is returned, containing the index of the matching element. If there are multiple matches, 767 | /// then any one of the matches could be returned. If the value is not found then Result::Err is returned, 768 | /// containing the index where a matching element could be inserted while maintaining sorted order. 769 | /// 770 | /// # Examples 771 | /// 772 | /// Looks up a series of four elements in a non-empty vector of pairs sorted by their second elements. 773 | /// The first is found, with a uniquely determined position; the second and third are not found; 774 | /// the fourth could match any position in [1, 4]. 775 | /// 776 | /// ``` 777 | /// use nonempty::NonEmpty; 778 | /// 779 | /// let non_empty = NonEmpty::from(( 780 | /// (0, 0), 781 | /// vec![(2, 1), (4, 1), (5, 1), (3, 1), 782 | /// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13), 783 | /// (1, 21), (2, 34), (4, 55)] 784 | /// )); 785 | /// 786 | /// assert_eq!(non_empty.binary_search_by_key(&0, |&(a,b)| b), Ok(0)); 787 | /// assert_eq!(non_empty.binary_search_by_key(&13, |&(a,b)| b), Ok(9)); 788 | /// assert_eq!(non_empty.binary_search_by_key(&4, |&(a,b)| b), Err(7)); 789 | /// assert_eq!(non_empty.binary_search_by_key(&100, |&(a,b)| b), Err(13)); 790 | /// let r = non_empty.binary_search_by_key(&1, |&(a,b)| b); 791 | /// assert!(match r { Ok(1..=4) => true, _ => false, }); 792 | /// ``` 793 | pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result 794 | where 795 | B: Ord, 796 | F: FnMut(&'a T) -> B, 797 | { 798 | self.binary_search_by(|k| f(k).cmp(b)) 799 | } 800 | 801 | /// Returns the maximum element in the non-empty vector. 802 | /// 803 | /// This will return the first item in the vector if the tail is empty. 804 | /// 805 | /// # Examples 806 | /// 807 | /// ``` 808 | /// use nonempty::NonEmpty; 809 | /// 810 | /// let non_empty = NonEmpty::new(42); 811 | /// assert_eq!(non_empty.maximum(), &42); 812 | /// 813 | /// let non_empty = NonEmpty::from((1, vec![-34, 42, 76, 4, 5])); 814 | /// assert_eq!(non_empty.maximum(), &76); 815 | /// ``` 816 | pub fn maximum(&self) -> &T 817 | where 818 | T: Ord, 819 | { 820 | self.maximum_by(|i, j| i.cmp(j)) 821 | } 822 | 823 | /// Returns the minimum element in the non-empty vector. 824 | /// 825 | /// This will return the first item in the vector if the tail is empty. 826 | /// 827 | /// # Examples 828 | /// 829 | /// ``` 830 | /// use nonempty::NonEmpty; 831 | /// 832 | /// let non_empty = NonEmpty::new(42); 833 | /// assert_eq!(non_empty.minimum(), &42); 834 | /// 835 | /// let non_empty = NonEmpty::from((1, vec![-34, 42, 76, 4, 5])); 836 | /// assert_eq!(non_empty.minimum(), &-34); 837 | /// ``` 838 | pub fn minimum(&self) -> &T 839 | where 840 | T: Ord, 841 | { 842 | self.minimum_by(|i, j| i.cmp(j)) 843 | } 844 | 845 | /// Returns the element that gives the maximum value with respect to the specified comparison function. 846 | /// 847 | /// This will return the first item in the vector if the tail is empty. 848 | /// 849 | /// # Examples 850 | /// 851 | /// ``` 852 | /// use nonempty::NonEmpty; 853 | /// 854 | /// let non_empty = NonEmpty::new((0, 42)); 855 | /// assert_eq!(non_empty.maximum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 42)); 856 | /// 857 | /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)])); 858 | /// assert_eq!(non_empty.maximum_by(|(k, _), (l, _)| k.cmp(l)), &(4, 42)); 859 | /// ``` 860 | pub fn maximum_by(&self, mut compare: F) -> &T 861 | where 862 | F: FnMut(&T, &T) -> Ordering, 863 | { 864 | let mut max = &self.head; 865 | for i in self.tail.iter() { 866 | max = match compare(max, i) { 867 | Ordering::Equal => max, 868 | Ordering::Less => i, 869 | Ordering::Greater => max, 870 | }; 871 | } 872 | max 873 | } 874 | 875 | /// Returns the element that gives the minimum value with respect to the specified comparison function. 876 | /// 877 | /// This will return the first item in the vector if the tail is empty. 878 | /// 879 | /// ``` 880 | /// use nonempty::NonEmpty; 881 | /// 882 | /// let non_empty = NonEmpty::new((0, 42)); 883 | /// assert_eq!(non_empty.minimum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 42)); 884 | /// 885 | /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)])); 886 | /// assert_eq!(non_empty.minimum_by(|(k, _), (l, _)| k.cmp(l)), &(0, 76)); 887 | /// ``` 888 | pub fn minimum_by(&self, mut compare: F) -> &T 889 | where 890 | F: FnMut(&T, &T) -> Ordering, 891 | { 892 | self.maximum_by(|a, b| compare(a, b).reverse()) 893 | } 894 | 895 | /// Returns the element that gives the maximum value with respect to the specified function. 896 | /// 897 | /// This will return the first item in the vector if the tail is empty. 898 | /// 899 | /// # Examples 900 | /// 901 | /// ``` 902 | /// use nonempty::NonEmpty; 903 | /// 904 | /// let non_empty = NonEmpty::new((0, 42)); 905 | /// assert_eq!(non_empty.maximum_by_key(|(k, _)| *k), &(0, 42)); 906 | /// 907 | /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)])); 908 | /// assert_eq!(non_empty.maximum_by_key(|(k, _)| *k), &(4, 42)); 909 | /// assert_eq!(non_empty.maximum_by_key(|(k, _)| -k), &(0, 76)); 910 | /// ``` 911 | pub fn maximum_by_key(&self, mut f: F) -> &T 912 | where 913 | U: Ord, 914 | F: FnMut(&T) -> U, 915 | { 916 | self.maximum_by(|i, j| f(i).cmp(&f(j))) 917 | } 918 | 919 | /// Returns the element that gives the minimum value with respect to the specified function. 920 | /// 921 | /// This will return the first item in the vector if the tail is empty. 922 | /// 923 | /// # Examples 924 | /// 925 | /// ``` 926 | /// use nonempty::NonEmpty; 927 | /// 928 | /// let non_empty = NonEmpty::new((0, 42)); 929 | /// assert_eq!(non_empty.minimum_by_key(|(k, _)| *k), &(0, 42)); 930 | /// 931 | /// let non_empty = NonEmpty::from(((2, 1), vec![(2, -34), (4, 42), (0, 76), (1, 4), (3, 5)])); 932 | /// assert_eq!(non_empty.minimum_by_key(|(k, _)| *k), &(0, 76)); 933 | /// assert_eq!(non_empty.minimum_by_key(|(k, _)| -k), &(4, 42)); 934 | /// ``` 935 | pub fn minimum_by_key(&self, mut f: F) -> &T 936 | where 937 | U: Ord, 938 | F: FnMut(&T) -> U, 939 | { 940 | self.minimum_by(|i, j| f(i).cmp(&f(j))) 941 | } 942 | 943 | /// Sorts the nonempty. 944 | /// 945 | /// The implementation uses [`slice::sort`](slice::sort) for the tail and then checks where the 946 | /// head belongs. If the head is already the smallest element, this should be as fast as sorting a 947 | /// slice. However, if the head needs to be inserted, then it incurs extra cost for removing 948 | /// the new head from the tail and adding the old head at the correct index. 949 | /// 950 | /// # Examples 951 | /// 952 | /// ``` 953 | /// use nonempty::nonempty; 954 | /// 955 | /// let mut non_empty = nonempty![-5, 4, 1, -3, 2]; 956 | /// 957 | /// non_empty.sort(); 958 | /// assert!(non_empty == nonempty![-5, -3, 1, 2, 4]); 959 | /// ``` 960 | pub fn sort(&mut self) 961 | where 962 | T: Ord, 963 | { 964 | self.tail.sort(); 965 | let index = match self.tail.binary_search(&self.head) { 966 | Ok(index) => index, 967 | Err(index) => index, 968 | }; 969 | 970 | if index != 0 { 971 | let new_head = self.tail.remove(0); 972 | let head = mem::replace(&mut self.head, new_head); 973 | self.tail.insert(index - 1, head); 974 | } 975 | } 976 | } 977 | 978 | impl Default for NonEmpty { 979 | fn default() -> Self { 980 | Self::new(T::default()) 981 | } 982 | } 983 | 984 | impl From> for Vec { 985 | /// Turns a non-empty list into a Vec. 986 | fn from(nonempty: NonEmpty) -> Vec { 987 | iter::once(nonempty.head).chain(nonempty.tail).collect() 988 | } 989 | } 990 | 991 | impl From> for (T, Vec) { 992 | /// Turns a non-empty list into a Vec. 993 | fn from(nonempty: NonEmpty) -> (T, Vec) { 994 | (nonempty.head, nonempty.tail) 995 | } 996 | } 997 | 998 | impl From<(T, Vec)> for NonEmpty { 999 | /// Turns a pair of an element and a Vec into 1000 | /// a NonEmpty. 1001 | fn from((head, tail): (T, Vec)) -> Self { 1002 | NonEmpty { head, tail } 1003 | } 1004 | } 1005 | 1006 | impl IntoIterator for NonEmpty { 1007 | type Item = T; 1008 | type IntoIter = iter::Chain, vec::IntoIter>; 1009 | 1010 | fn into_iter(self) -> Self::IntoIter { 1011 | iter::once(self.head).chain(self.tail) 1012 | } 1013 | } 1014 | 1015 | impl<'a, T> IntoIterator for &'a NonEmpty { 1016 | type Item = &'a T; 1017 | type IntoIter = iter::Chain, core::slice::Iter<'a, T>>; 1018 | 1019 | fn into_iter(self) -> Self::IntoIter { 1020 | iter::once(&self.head).chain(self.tail.iter()) 1021 | } 1022 | } 1023 | 1024 | impl core::ops::Index for NonEmpty { 1025 | type Output = T; 1026 | 1027 | /// ``` 1028 | /// use nonempty::NonEmpty; 1029 | /// 1030 | /// let non_empty = NonEmpty::from((1, vec![2, 3, 4, 5])); 1031 | /// 1032 | /// assert_eq!(non_empty[0], 1); 1033 | /// assert_eq!(non_empty[1], 2); 1034 | /// assert_eq!(non_empty[3], 4); 1035 | /// ``` 1036 | fn index(&self, index: usize) -> &T { 1037 | if index > 0 { 1038 | &self.tail[index - 1] 1039 | } else { 1040 | &self.head 1041 | } 1042 | } 1043 | } 1044 | 1045 | impl core::ops::IndexMut for NonEmpty { 1046 | fn index_mut(&mut self, index: usize) -> &mut T { 1047 | if index > 0 { 1048 | &mut self.tail[index - 1] 1049 | } else { 1050 | &mut self.head 1051 | } 1052 | } 1053 | } 1054 | 1055 | impl Extend for NonEmpty { 1056 | fn extend>(&mut self, iter: T) { 1057 | self.tail.extend(iter) 1058 | } 1059 | } 1060 | 1061 | #[cfg(feature = "serialize")] 1062 | pub mod serialize { 1063 | use core::{convert::TryFrom, fmt}; 1064 | 1065 | use alloc::vec::Vec; 1066 | 1067 | use super::NonEmpty; 1068 | 1069 | #[derive(Debug)] 1070 | pub enum Error { 1071 | Empty, 1072 | } 1073 | 1074 | impl fmt::Display for Error { 1075 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1076 | match self { 1077 | Self::Empty => f.write_str( 1078 | "the vector provided was empty, NonEmpty needs at least one element", 1079 | ), 1080 | } 1081 | } 1082 | } 1083 | 1084 | impl TryFrom> for NonEmpty { 1085 | type Error = Error; 1086 | 1087 | fn try_from(vec: Vec) -> Result { 1088 | NonEmpty::from_vec(vec).ok_or(Error::Empty) 1089 | } 1090 | } 1091 | } 1092 | 1093 | #[cfg(test)] 1094 | mod tests { 1095 | use alloc::{string::String, vec::Vec}; 1096 | 1097 | use crate::NonEmpty; 1098 | 1099 | #[test] 1100 | fn test_from_conversion() { 1101 | let result = NonEmpty::from((1, vec![2, 3, 4, 5])); 1102 | let expected = NonEmpty { 1103 | head: 1, 1104 | tail: vec![2, 3, 4, 5], 1105 | }; 1106 | assert_eq!(result, expected); 1107 | } 1108 | 1109 | #[test] 1110 | fn test_into_iter() { 1111 | let nonempty = NonEmpty::from((0, vec![1, 2, 3])); 1112 | for (i, n) in nonempty.into_iter().enumerate() { 1113 | assert_eq!(i as i32, n); 1114 | } 1115 | } 1116 | 1117 | #[test] 1118 | fn test_iter_syntax() { 1119 | let nonempty = NonEmpty::from((0, vec![1, 2, 3])); 1120 | for n in &nonempty { 1121 | let _ = *n; // Prove that we're dealing with references. 1122 | } 1123 | for _ in nonempty {} 1124 | } 1125 | 1126 | #[test] 1127 | fn test_iter_both_directions() { 1128 | let mut nonempty = NonEmpty::from((0, vec![1, 2, 3])); 1129 | assert_eq!(nonempty.iter().cloned().collect::>(), [0, 1, 2, 3]); 1130 | assert_eq!( 1131 | nonempty.iter().rev().cloned().collect::>(), 1132 | [3, 2, 1, 0] 1133 | ); 1134 | assert_eq!( 1135 | nonempty.iter_mut().rev().collect::>(), 1136 | [&mut 3, &mut 2, &mut 1, &mut 0] 1137 | ); 1138 | } 1139 | 1140 | #[test] 1141 | fn test_iter_both_directions_at_once() { 1142 | let nonempty = NonEmpty::from((0, vec![1, 2, 3])); 1143 | let mut i = nonempty.iter(); 1144 | assert_eq!(i.next(), Some(&0)); 1145 | assert_eq!(i.next_back(), Some(&3)); 1146 | assert_eq!(i.next(), Some(&1)); 1147 | assert_eq!(i.next_back(), Some(&2)); 1148 | assert_eq!(i.next(), None); 1149 | assert_eq!(i.next_back(), None); 1150 | } 1151 | 1152 | #[test] 1153 | fn test_mutate_head() { 1154 | let mut non_empty = NonEmpty::new(42); 1155 | non_empty.head += 1; 1156 | assert_eq!(non_empty.head, 43); 1157 | 1158 | let mut non_empty = NonEmpty::from((1, vec![4, 2, 3])); 1159 | non_empty.head *= 42; 1160 | assert_eq!(non_empty.head, 42); 1161 | } 1162 | 1163 | #[test] 1164 | fn test_to_nonempty() { 1165 | use core::iter::{empty, once}; 1166 | 1167 | assert_eq!(NonEmpty::<()>::collect(empty()), None); 1168 | assert_eq!(NonEmpty::<()>::collect(once(())), Some(NonEmpty::new(()))); 1169 | assert_eq!( 1170 | NonEmpty::::collect(once(1).chain(once(2))), 1171 | Some(nonempty!(1, 2)) 1172 | ); 1173 | } 1174 | 1175 | #[test] 1176 | fn test_try_map() { 1177 | assert_eq!( 1178 | nonempty!(1, 2, 3, 4).try_map(Ok::<_, String>), 1179 | Ok(nonempty!(1, 2, 3, 4)) 1180 | ); 1181 | assert_eq!( 1182 | nonempty!(1, 2, 3, 4).try_map(|i| if i % 2 == 0 { Ok(i) } else { Err("not even") }), 1183 | Err("not even") 1184 | ); 1185 | } 1186 | 1187 | #[test] 1188 | fn test_nontrivial_minimum_by_key() { 1189 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 1190 | struct Position { 1191 | x: i32, 1192 | y: i32, 1193 | } 1194 | impl Position { 1195 | pub fn distance_squared(&self, other: Position) -> u32 { 1196 | let dx = self.x - other.x; 1197 | let dy = self.y - other.y; 1198 | (dx * dx + dy * dy) as u32 1199 | } 1200 | } 1201 | let positions = nonempty![ 1202 | Position { x: 1, y: 1 }, 1203 | Position { x: 0, y: 0 }, 1204 | Position { x: 3, y: 4 } 1205 | ]; 1206 | let target = Position { x: 1, y: 2 }; 1207 | let closest = positions.minimum_by_key(|position| position.distance_squared(target)); 1208 | assert_eq!(closest, &Position { x: 1, y: 1 }); 1209 | } 1210 | 1211 | #[test] 1212 | fn test_sort() { 1213 | let mut numbers = nonempty![1]; 1214 | numbers.sort(); 1215 | assert_eq!(numbers, nonempty![1]); 1216 | 1217 | let mut numbers = nonempty![2, 1, 3]; 1218 | numbers.sort(); 1219 | assert_eq!(numbers, nonempty![1, 2, 3]); 1220 | 1221 | let mut numbers = nonempty![1, 3, 2]; 1222 | numbers.sort(); 1223 | assert_eq!(numbers, nonempty![1, 2, 3]); 1224 | 1225 | let mut numbers = nonempty![3, 2, 1]; 1226 | numbers.sort(); 1227 | assert_eq!(numbers, nonempty![1, 2, 3]); 1228 | } 1229 | 1230 | #[cfg(feature = "serialize")] 1231 | mod serialize { 1232 | use crate::NonEmpty; 1233 | use alloc::boxed::Box; 1234 | use serde::{Deserialize, Serialize}; 1235 | 1236 | #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] 1237 | pub struct SimpleSerializable(pub i32); 1238 | 1239 | #[test] 1240 | fn test_simple_round_trip() -> Result<(), Box> { 1241 | // Given 1242 | let mut non_empty = NonEmpty::new(SimpleSerializable(42)); 1243 | non_empty.push(SimpleSerializable(777)); 1244 | 1245 | // When 1246 | let res = serde_json::from_str::<'_, NonEmpty>( 1247 | &serde_json::to_string(&non_empty)?, 1248 | )?; 1249 | 1250 | // Then 1251 | assert_eq!(res, non_empty); 1252 | 1253 | Ok(()) 1254 | } 1255 | 1256 | #[test] 1257 | fn test_serialization() -> Result<(), Box> { 1258 | let ne = nonempty![1, 2, 3, 4, 5]; 1259 | let ve = vec![1, 2, 3, 4, 5]; 1260 | 1261 | assert_eq!(serde_json::to_string(&ne)?, serde_json::to_string(&ve)?); 1262 | 1263 | Ok(()) 1264 | } 1265 | } 1266 | 1267 | #[cfg(feature = "arbitrary")] 1268 | mod arbitrary { 1269 | use crate::NonEmpty; 1270 | use arbitrary::{Arbitrary, Unstructured}; 1271 | 1272 | #[test] 1273 | fn test_arbitrary_empty_tail() -> arbitrary::Result<()> { 1274 | let mut u = Unstructured::new(&[1, 2, 3, 4]); 1275 | let ne = NonEmpty::::arbitrary(&mut u)?; 1276 | assert!(!ne.is_empty()); 1277 | assert_eq!( 1278 | ne, 1279 | NonEmpty { 1280 | head: 67305985, 1281 | tail: vec![], 1282 | } 1283 | ); 1284 | Ok(()) 1285 | } 1286 | 1287 | #[test] 1288 | fn test_arbitrary_with_tail() -> arbitrary::Result<()> { 1289 | let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]); 1290 | let ne = NonEmpty::::arbitrary(&mut u)?; 1291 | assert!(!ne.is_empty()); 1292 | assert_eq!( 1293 | ne, 1294 | NonEmpty { 1295 | head: 67305985, 1296 | tail: vec![526086], 1297 | } 1298 | ); 1299 | Ok(()) 1300 | } 1301 | 1302 | #[test] 1303 | fn test_arbitrary_with_split() -> arbitrary::Result<()> { 1304 | let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]); 1305 | let ne = NonEmpty::::arbitrary(&mut u)?; 1306 | let (head, middle, last) = ne.split(); 1307 | let mut tail = middle.to_vec(); 1308 | tail.extend(last); 1309 | assert_eq!(ne, NonEmpty { head: *head, tail }); 1310 | Ok(()) 1311 | } 1312 | } 1313 | } 1314 | -------------------------------------------------------------------------------- /src/nonzero.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "arbitrary")] 2 | use arbitrary::Arbitrary; 3 | use core::num::NonZeroUsize; 4 | 5 | /// A non-empty list which statically guarantees certain operations 6 | /// cannot return zero, using [`core::num::NonZeroUsize`]. 7 | /// 8 | /// *Experimental* 9 | /// 10 | #[repr(transparent)] 11 | #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] 12 | #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 13 | pub struct NonEmpty(super::NonEmpty); 14 | 15 | impl NonEmpty { 16 | /// Get the length of the list. 17 | pub fn len(&self) -> NonZeroUsize { 18 | unsafe { NonZeroUsize::new_unchecked(self.0.tail.len() + 1) } 19 | } 20 | 21 | /// Get the capacity of the list. 22 | pub fn capacity(&self) -> NonZeroUsize { 23 | unsafe { NonZeroUsize::new_unchecked(self.0.tail.capacity() + 1) } 24 | } 25 | 26 | /// Truncate the list to a certain size. 27 | pub fn truncate(&mut self, len: NonZeroUsize) { 28 | self.tail.truncate(usize::from(len) - 1); 29 | } 30 | } 31 | 32 | impl From> for NonEmpty { 33 | fn from(other: super::NonEmpty) -> NonEmpty { 34 | NonEmpty(other) 35 | } 36 | } 37 | 38 | impl core::ops::Deref for NonEmpty { 39 | type Target = super::NonEmpty; 40 | 41 | fn deref(&self) -> &Self::Target { 42 | &self.0 43 | } 44 | } 45 | 46 | impl core::ops::DerefMut for NonEmpty { 47 | fn deref_mut(&mut self) -> &mut Self::Target { 48 | &mut self.0 49 | } 50 | } 51 | 52 | #[cfg(test)] 53 | mod tests { 54 | use crate::nonzero; 55 | use crate::NonEmpty; 56 | 57 | use core::convert::TryInto; 58 | 59 | #[test] 60 | fn test_nonzero() { 61 | let nonempty: nonzero::NonEmpty<_> = NonEmpty::from((0, vec![1, 2, 3])).into(); 62 | 63 | assert_eq!(nonempty.len(), 4.try_into().unwrap()); 64 | assert_eq!(nonempty.capacity(), 4.try_into().unwrap()); 65 | } 66 | 67 | #[cfg(feature = "arbitrary")] 68 | mod arbitrary { 69 | use crate::nonzero; 70 | use arbitrary::{Arbitrary, Unstructured}; 71 | 72 | use core::convert::TryInto; 73 | 74 | #[test] 75 | fn test_nonzero_arbitrary_empty_tail() -> arbitrary::Result<()> { 76 | let mut u = Unstructured::new(&[1, 2, 3, 4]); 77 | let nonempty: nonzero::NonEmpty<_> = nonzero::NonEmpty::::arbitrary(&mut u)?; 78 | 79 | assert_eq!(nonempty.len(), 1.try_into().unwrap()); 80 | assert_eq!(nonempty.capacity(), 1.try_into().unwrap()); 81 | 82 | Ok(()) 83 | } 84 | 85 | #[test] 86 | fn test_nonzero_arbitrary_with_tail() -> arbitrary::Result<()> { 87 | let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]); 88 | let nonempty: nonzero::NonEmpty<_> = nonzero::NonEmpty::::arbitrary(&mut u)?; 89 | 90 | assert_eq!(nonempty.len(), 2.try_into().unwrap()); 91 | assert_eq!(nonempty.capacity(), 5.try_into().unwrap()); 92 | 93 | Ok(()) 94 | } 95 | } 96 | } 97 | --------------------------------------------------------------------------------