├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── benches └── vec.rs ├── justfile ├── rust-toolchain-nightly ├── rustfmt.toml └── src ├── array.rs ├── either.rs ├── index_map.rs ├── iter.rs ├── itertools.rs ├── lib.rs ├── map.rs ├── set.rs ├── slice.rs └── vector.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | on: 5 | push: 6 | branches: [master] 7 | pull_request: 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | test: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Put Rust toolchain in environment variable 20 | run: | 21 | echo "RUST_TOOLCHAIN=$(cat ./rust-toolchain)" >> $GITHUB_ENV 22 | 23 | - uses: dtolnay/rust-toolchain@master 24 | with: 25 | toolchain: ${{ env.RUST_TOOLCHAIN }} 26 | components: clippy 27 | 28 | - name: Cache Dependencies 29 | uses: Swatinem/rust-cache@v2 30 | 31 | - uses: taiki-e/install-action@v2 32 | with: 33 | tool: just 34 | 35 | - name: Run tests 36 | run: just test 37 | 38 | lint: 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v4 43 | 44 | - uses: taiki-e/install-action@v2 45 | with: 46 | tool: just 47 | 48 | - name: Put Rust toolchains in environment variables 49 | run: | 50 | echo "RUST_TOOLCHAIN=$(cat ./rust-toolchain)" >> $GITHUB_ENV 51 | echo "RUST_TOOLCHAIN_NIGHTLY=$(cat ./rust-toolchain-nightly)" >> $GITHUB_ENV 52 | 53 | # nightly is needed for the rustfmt portion of the lint command 54 | - uses: dtolnay/rust-toolchain@master 55 | with: 56 | toolchain: ${{ env.RUST_TOOLCHAIN_NIGHTLY }} 57 | components: rustfmt 58 | 59 | - uses: dtolnay/rust-toolchain@master 60 | with: 61 | toolchain: ${{ env.RUST_TOOLCHAIN }} 62 | components: clippy 63 | 64 | - name: Cache Dependencies 65 | uses: Swatinem/rust-cache@v2 66 | 67 | - name: Run lint 68 | run: just lint 69 | 70 | check-readme: 71 | runs-on: ubuntu-latest 72 | 73 | steps: 74 | - uses: actions/checkout@v4 75 | 76 | - uses: taiki-e/install-action@v2 77 | with: 78 | tool: just,cargo-rdme 79 | 80 | - name: Check readme 81 | run: just check-readme 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # `nonempty-collections` 2 | 3 | ## Unreleased 4 | 5 | #### Added 6 | 7 | - `iter_mut()` to `NEVec`, `NEMap`, and `NEIndexMap` 8 | - `peekable()` to `NonEmptyIterator` 9 | - `remove()`, `swap_remove()`, `retain()`, and `retain_mut()` to `NEVec`. 10 | - `AsRef<[T]>` for `NESlice`. 11 | 12 | ## 0.3.0 (2025-02-15) 13 | 14 | #### Changed 15 | 16 | - **BREAKING:** Redesign of `NonEmptyIterator`: 17 | - `NonEmptyIterator` is now bounded by `IntoIterator` and has default 18 | implementations of all methods (i.e. it is a marker trait). 19 | - `NonEmptyIterator::first()` is renamed to `next()` and the old implementation of `next()` is removed. 20 | - `NonEmptyIterator::all()` now consumes self 21 | - `NonEmptyIterator::any()` now consumes self 22 | - `NonEmptyIterator::nth()` now consumes self 23 | - `NonEmptyIterator::take(usize)` -> `NonEmptyIterator::take(NonZeroUsize)` and doesn't panic anymore 24 | - **BREAKING:** `NEVec::truncate(usize)` -> `NEVec::truncate(NonZeroUsize)` and doesn't panic anymore 25 | - **BREAKING:** Capacities for all collections now use `NonZeroUsize` instead of `usize`: 26 | - `with_capacity(NonZeroUsize)` 27 | - `with_capacity_and_hasher(NonZeroUsize)` 28 | - `capacity() -> NonZeroUsize` 29 | - **BREAKING:** All fields are now private for `NEVec`, `NEMap`, `NESet`, and `NESlice` 30 | - **BREAKING:** Removed: 31 | - `NESlice::new(&T, &[T])` 32 | - `IntoIteratorProxy` 33 | - **BREAKING:** Methods that are no longer `const`: 34 | - `NEVec::new()` 35 | - `NEVec::first()` 36 | - **BREAKING:** non-empty maps and sets now behave similarly to their possibly 37 | empty counter parts: when created from an iterator with duplicates, the last 38 | occurence is kept. 39 | - **BREAKING:** Consistent API, new naming to align with Rust's naming 40 | conventions and indicate the fallibility of the function: 41 | - `from_vec` to `try_from_vec` 42 | - `from_map` to `try_from_map` 43 | - `from_slice` to `try_from_slice` 44 | - `from_set` to `try_from_set`. 45 | - **BREAKING:** `IteratorExt` is removed in favor of `IntoIteratorExt`. Now it's 46 | possible to call `try_into_nonempty_iter()` instead of `to_nonempty_iter()` on 47 | all regular iterators because regular iterators also implement `IntoIterator`. 48 | - **BREAKING:** `.iter()`, `.iter_mut()`, etc, are now prefixed with `nonempty_` 49 | - `FromNonEmptyIterator` is now implemented for `HashSet` instead of 50 | `HashSet` (with the default hasher). 51 | 52 | #### Fixed 53 | 54 | - Fixes bug in `PartialEq for NEIndexMap`, previously, maps with unequal lengths 55 | would be considered equal if the shorter map would contain the same values as 56 | the longer map. 57 | - Fixes bug in `NEMap::with_capacity()` and `NESet::with_capacity()`, it wasn't 58 | possible to call this method without explicitly specifying the type for `S` 59 | (the hasher). For this method it is assumed that it always uses the default 60 | hasher (just like in `std`), in case the user wants to specify the hasher 61 | `with_capacity_and_hasher()` can be used. The fix moved the method into the 62 | proper `impl` block. 63 | 64 | #### Added 65 | 66 | - New feature `either`: adds `NEEither` an extension to `either::Either`. 67 | - New feature `itertools`: adds a new `NonEmptyItertools` trait that is an 68 | extension of the `NonEmptyIterator` similar to how `Itertools` extends 69 | `Iterator`. So far, `cartesian_product()`, `sorted_by_key()`, and 70 | `all_unique()` are implemented. 71 | - `NonEmptyIterator::find()` the equivalent of `Iterator::find()`. 72 | - `IntoNonEmptyIterator for &NEVec`, `&NEIndexMap`, `&NEMap`, `&NESet`, 73 | `&NESlice`, `&[T; $i] where $i > 0` (these previously only existed for their 74 | owned equivalents) 75 | - `NESlice::from_slice()` is now `const` 76 | - `Index for NESlice` 77 | - All public types now implement `Debug` 78 | - Aliases `ne_vec` for `nev`, `ne_hashset` for `nes`, and `ne_hashmap` for `nem`. 79 | - Strict lint configuration 80 | - The rust version to which the library is build is now pinned, to avoid accidental breakage. 81 | - A [`justfile`](https://github.com/casey/just) that allows to run 82 | pre-configured commands to check the codebase. E.g. `just lint` or `just 83 | test`. 84 | - Benchmarks for `Vec` versus `NEVec`. 85 | - Added `.iter()` methods to all collections returning a regular `Iterator`. 86 | 87 | ## 0.2.9 (2024-08-26) 88 | 89 | #### Added 90 | 91 | - `NonEmptyIterator::group_by`. 92 | - `NVec::sort_by` and `NEVec::sort_by_key`. 93 | - An impl of `Extend` for `NEVec`. 94 | 95 | #### Fixed 96 | 97 | - `NEVec::sort` avoids a second internal `sort`. 98 | 99 | ## 0.2.8 (2024-08-19) 100 | 101 | #### Added 102 | 103 | - Missing `FromNonEmptyIterator` for `HashMap`. 104 | 105 | ## 0.2.7 (2024-07-22) 106 | 107 | #### Added 108 | 109 | - `serde` support for `NEMap` and `NESet`. 110 | 111 | ## 0.2.6 (2024-06-27) 112 | 113 | #### Fixed 114 | 115 | - Ownership issues in `nem!` when using non-Copy types. 116 | 117 | ## 0.2.5 (2024-04-09) 118 | 119 | #### Added 120 | 121 | - Implementation of `NonEmptyIterator` for fixed-sized stdlib Arrays. 122 | 123 | ## 0.2.4 (2024-04-04) 124 | 125 | #### Added 126 | 127 | - Added `NEVec::partition_point` to match the function of the same name in `std`. 128 | 129 | #### Fixed 130 | 131 | - Render feature-gated types on `docs.rs`. 132 | 133 | ## 0.2.3 (2024-03-19) 134 | 135 | #### Fixed 136 | 137 | - More edge cases involving `NEChunks`. 138 | 139 | ## 0.2.2 (2024-03-18) 140 | 141 | #### Fixed 142 | 143 | - `IntoIterator` for `NEChunks` yielding the wrong type. 144 | - `NonEmptyIterator` for `NEChunks` missing a cutoff condition. 145 | 146 | ## 0.2.1 (2024-03-15) 147 | 148 | #### Added 149 | 150 | - The missing `IntoIterator` impl for `NEChunks`. 151 | - `IntoIteratorExt` for direct conversion from anything that implements 152 | `IntoIterator`. Thanks to Rinde van Lon. 153 | 154 | #### Fixed 155 | 156 | - A bug involving repeated keys in `NEMap` and `NEIndexedMap`. Thanks to Rinde van Lon. 157 | 158 | ## 0.2.0 (2024-03-14) 159 | 160 | #### Added 161 | 162 | - `NEIndexMap`, thanks to [Rinde van Lon](https://github.com/rinde/). 163 | - `NonEmptyIterator::max_by_key` and `NonEmptyIterator::min_by_key`, also thanks to Rinde. 164 | - `NEVec::with_capacity` 165 | - `NEVec::nonempty_chunks` and `NESlice::nonempty_chunks` 166 | 167 | #### Changed 168 | 169 | - **BREAKING:** All `len` implementations and `NonEmptyIterator::count` have had 170 | their return type changed to `NonZeroUsize`. 171 | 172 | ## 0.1.5 (2024-01-12) 173 | 174 | #### Added 175 | 176 | - `NonEmptyIterator::reduce`, which yields a concrete `Self::Item` instead of an 177 | `Option`. 178 | - `IteratorExt::to_nonempty_iter` for converting any given `Iterator` into a 179 | non-empty one (if possible). 180 | - The `NEVec::dedup*` series for removing duplicate items in-place. 181 | 182 | #### Fixed 183 | 184 | - Account for potentially duplicated `head` value when converting into an 185 | `NESet` from other nonempty iterators. 186 | 187 | ## 0.1.4 (2023-11-02) 188 | 189 | #### Added 190 | 191 | - `FromNonEmptyIterator` impls for `NEMap` and `NESet`. 192 | - `Debug`, `Clone`, `PartialEq`, and `Eq` for `NEMap`. 193 | 194 | ## 0.1.3 (2023-09-15) 195 | 196 | #### Added 197 | 198 | - `NESlice` for when what you have on hand is already borrowed. Thanks again to 199 | Greg Shuflin. 200 | 201 | ## 0.1.2 (2023-09-05) 202 | 203 | #### Added 204 | 205 | - A `FromNonEmptyIterator` instance for `Result`, meaning you can `collect` into 206 | a guaranteed `Result, Error>` (or other nonempty type). Thanks to 207 | Greg Shuflin. 208 | 209 | ## 0.1.1 (2023-04-08) 210 | 211 | #### Added 212 | 213 | - Missing `IntoNonEmptyIterator` instances. 214 | - Missing `Intoiterator` instance for `FlatMap`. 215 | 216 | #### Fixed 217 | 218 | - Incorrect `IntoIterator` for `Take`. 219 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "anstyle" 7 | version = "1.0.8" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 10 | 11 | [[package]] 12 | name = "bitflags" 13 | version = "2.6.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 16 | 17 | [[package]] 18 | name = "cfg-if" 19 | version = "1.0.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 22 | 23 | [[package]] 24 | name = "clap" 25 | version = "4.5.17" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" 28 | dependencies = [ 29 | "clap_builder", 30 | ] 31 | 32 | [[package]] 33 | name = "clap_builder" 34 | version = "4.5.17" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" 37 | dependencies = [ 38 | "anstyle", 39 | "clap_lex", 40 | "terminal_size", 41 | ] 42 | 43 | [[package]] 44 | name = "clap_lex" 45 | version = "0.7.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 48 | 49 | [[package]] 50 | name = "condtype" 51 | version = "1.3.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" 54 | 55 | [[package]] 56 | name = "divan" 57 | version = "0.1.17" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "e0583193020b29b03682d8d33bb53a5b0f50df6daacece12ca99b904cfdcb8c4" 60 | dependencies = [ 61 | "cfg-if", 62 | "clap", 63 | "condtype", 64 | "divan-macros", 65 | "libc", 66 | "regex-lite", 67 | ] 68 | 69 | [[package]] 70 | name = "divan-macros" 71 | version = "0.1.17" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "8dc51d98e636f5e3b0759a39257458b22619cac7e96d932da6eeb052891bb67c" 74 | dependencies = [ 75 | "proc-macro2", 76 | "quote", 77 | "syn", 78 | ] 79 | 80 | [[package]] 81 | name = "either" 82 | version = "1.13.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 85 | 86 | [[package]] 87 | name = "equivalent" 88 | version = "1.0.1" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 91 | 92 | [[package]] 93 | name = "errno" 94 | version = "0.3.9" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 97 | dependencies = [ 98 | "libc", 99 | "windows-sys 0.52.0", 100 | ] 101 | 102 | [[package]] 103 | name = "hashbrown" 104 | version = "0.15.2" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 107 | 108 | [[package]] 109 | name = "indexmap" 110 | version = "2.7.1" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 113 | dependencies = [ 114 | "equivalent", 115 | "hashbrown", 116 | ] 117 | 118 | [[package]] 119 | name = "itertools" 120 | version = "0.14.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 123 | dependencies = [ 124 | "either", 125 | ] 126 | 127 | [[package]] 128 | name = "itoa" 129 | version = "1.0.6" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 132 | 133 | [[package]] 134 | name = "libc" 135 | version = "0.2.158" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" 138 | 139 | [[package]] 140 | name = "linux-raw-sys" 141 | version = "0.4.14" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 144 | 145 | [[package]] 146 | name = "maplit" 147 | version = "1.0.2" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 150 | 151 | [[package]] 152 | name = "memchr" 153 | version = "2.7.4" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 156 | 157 | [[package]] 158 | name = "nonempty-collections" 159 | version = "0.3.0" 160 | dependencies = [ 161 | "divan", 162 | "either", 163 | "indexmap", 164 | "itertools", 165 | "maplit", 166 | "serde", 167 | "serde_json", 168 | ] 169 | 170 | [[package]] 171 | name = "proc-macro2" 172 | version = "1.0.86" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 175 | dependencies = [ 176 | "unicode-ident", 177 | ] 178 | 179 | [[package]] 180 | name = "quote" 181 | version = "1.0.37" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 184 | dependencies = [ 185 | "proc-macro2", 186 | ] 187 | 188 | [[package]] 189 | name = "regex-lite" 190 | version = "0.1.6" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" 193 | 194 | [[package]] 195 | name = "rustix" 196 | version = "0.38.36" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" 199 | dependencies = [ 200 | "bitflags", 201 | "errno", 202 | "libc", 203 | "linux-raw-sys", 204 | "windows-sys 0.52.0", 205 | ] 206 | 207 | [[package]] 208 | name = "ryu" 209 | version = "1.0.13" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 212 | 213 | [[package]] 214 | name = "serde" 215 | version = "1.0.217" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 218 | dependencies = [ 219 | "serde_derive", 220 | ] 221 | 222 | [[package]] 223 | name = "serde_derive" 224 | version = "1.0.217" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 227 | dependencies = [ 228 | "proc-macro2", 229 | "quote", 230 | "syn", 231 | ] 232 | 233 | [[package]] 234 | name = "serde_json" 235 | version = "1.0.138" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" 238 | dependencies = [ 239 | "itoa", 240 | "memchr", 241 | "ryu", 242 | "serde", 243 | ] 244 | 245 | [[package]] 246 | name = "syn" 247 | version = "2.0.87" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" 250 | dependencies = [ 251 | "proc-macro2", 252 | "quote", 253 | "unicode-ident", 254 | ] 255 | 256 | [[package]] 257 | name = "terminal_size" 258 | version = "0.3.0" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" 261 | dependencies = [ 262 | "rustix", 263 | "windows-sys 0.48.0", 264 | ] 265 | 266 | [[package]] 267 | name = "unicode-ident" 268 | version = "1.0.8" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 271 | 272 | [[package]] 273 | name = "windows-sys" 274 | version = "0.48.0" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 277 | dependencies = [ 278 | "windows-targets 0.48.5", 279 | ] 280 | 281 | [[package]] 282 | name = "windows-sys" 283 | version = "0.52.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 286 | dependencies = [ 287 | "windows-targets 0.52.6", 288 | ] 289 | 290 | [[package]] 291 | name = "windows-targets" 292 | version = "0.48.5" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 295 | dependencies = [ 296 | "windows_aarch64_gnullvm 0.48.5", 297 | "windows_aarch64_msvc 0.48.5", 298 | "windows_i686_gnu 0.48.5", 299 | "windows_i686_msvc 0.48.5", 300 | "windows_x86_64_gnu 0.48.5", 301 | "windows_x86_64_gnullvm 0.48.5", 302 | "windows_x86_64_msvc 0.48.5", 303 | ] 304 | 305 | [[package]] 306 | name = "windows-targets" 307 | version = "0.52.6" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 310 | dependencies = [ 311 | "windows_aarch64_gnullvm 0.52.6", 312 | "windows_aarch64_msvc 0.52.6", 313 | "windows_i686_gnu 0.52.6", 314 | "windows_i686_gnullvm", 315 | "windows_i686_msvc 0.52.6", 316 | "windows_x86_64_gnu 0.52.6", 317 | "windows_x86_64_gnullvm 0.52.6", 318 | "windows_x86_64_msvc 0.52.6", 319 | ] 320 | 321 | [[package]] 322 | name = "windows_aarch64_gnullvm" 323 | version = "0.48.5" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 326 | 327 | [[package]] 328 | name = "windows_aarch64_gnullvm" 329 | version = "0.52.6" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 332 | 333 | [[package]] 334 | name = "windows_aarch64_msvc" 335 | version = "0.48.5" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 338 | 339 | [[package]] 340 | name = "windows_aarch64_msvc" 341 | version = "0.52.6" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 344 | 345 | [[package]] 346 | name = "windows_i686_gnu" 347 | version = "0.48.5" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 350 | 351 | [[package]] 352 | name = "windows_i686_gnu" 353 | version = "0.52.6" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 356 | 357 | [[package]] 358 | name = "windows_i686_gnullvm" 359 | version = "0.52.6" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 362 | 363 | [[package]] 364 | name = "windows_i686_msvc" 365 | version = "0.48.5" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 368 | 369 | [[package]] 370 | name = "windows_i686_msvc" 371 | version = "0.52.6" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 374 | 375 | [[package]] 376 | name = "windows_x86_64_gnu" 377 | version = "0.48.5" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 380 | 381 | [[package]] 382 | name = "windows_x86_64_gnu" 383 | version = "0.52.6" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 386 | 387 | [[package]] 388 | name = "windows_x86_64_gnullvm" 389 | version = "0.48.5" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 392 | 393 | [[package]] 394 | name = "windows_x86_64_gnullvm" 395 | version = "0.52.6" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 398 | 399 | [[package]] 400 | name = "windows_x86_64_msvc" 401 | version = "0.48.5" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 404 | 405 | [[package]] 406 | name = "windows_x86_64_msvc" 407 | version = "0.52.6" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 410 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nonempty-collections" 3 | version = "0.3.0" 4 | description = "Correct-by-construction non-empty collections." 5 | authors = ["Colin Woodbury "] 6 | edition = "2021" 7 | license = "MIT" 8 | repository = "https://github.com/fosskers/nonempty-collections" 9 | readme = "README.md" 10 | keywords = ["nonempty", "vector", "set", "map"] 11 | categories = ["data-structures"] 12 | 13 | [dependencies] 14 | serde = { version = "1.0", features = ["serde_derive"], optional = true } 15 | indexmap = { version = "2.7", optional = true } 16 | either = { version = "1.0", optional = true } 17 | itertools = { version = "0.14", optional = true, features = ["use_alloc"] } 18 | 19 | [dev-dependencies] 20 | serde_json = "1.0" 21 | divan = "0.1" 22 | maplit = "1.0" 23 | 24 | [[bench]] 25 | name = "vec" 26 | harness = false 27 | 28 | [lints.rust] 29 | macro_use_extern_crate = "warn" 30 | meta_variable_misuse = "warn" 31 | missing_copy_implementations = "warn" 32 | missing_debug_implementations = "warn" 33 | missing_docs = "warn" 34 | single_use_lifetimes = "warn" 35 | unreachable_pub = "warn" 36 | unsafe_code = "allow" 37 | unstable_features = "deny" 38 | unused = { level = "warn", priority = -1 } 39 | unused_crate_dependencies = "allow" # too many false positives 40 | unused_extern_crates = "allow" # too many false positives 41 | unused_import_braces = "warn" 42 | unused_lifetimes = "warn" 43 | unused_macro_rules = "warn" 44 | unused_qualifications = "warn" 45 | unused_results = "allow" 46 | dead_code = "warn" 47 | 48 | [lints.rustdoc] 49 | broken_intra_doc_links = "deny" 50 | missing_crate_level_docs = "warn" 51 | 52 | [lints.clippy] 53 | cargo = { level = "warn", priority = -1 } 54 | complexity = { level = "warn", priority = -1 } 55 | correctness = { level = "deny", priority = -1 } 56 | perf = { level = "warn", priority = -1 } 57 | style = { level = "warn", priority = -1 } 58 | suspicious = { level = "deny", priority = -1 } 59 | todo = "warn" 60 | missing_const_for_fn = "warn" 61 | 62 | ### Pedantic 63 | pedantic = { level = "warn", priority = -1 } # setting a lower priority for the group to allow individual overrides 64 | module_name_repetitions = "allow" # naming is hard enough already 65 | 66 | [package.metadata.docs.rs] 67 | all-features = true 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Colin Woodbury 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 Collections 2 | 3 | 4 | 5 | Non-empty variants of the standard collections. 6 | 7 | Non-emptiness can be a powerful guarantee. If your main use of `Vec` is as 8 | an `Iterator`, then you may not need to distinguish on emptiness. But there 9 | are indeed times when the `Vec` you receive as a function argument needs to 10 | be non-empty or your function can't proceed. Similarly, there are times when 11 | the `Vec` you return to a calling user needs to promise it actually contains 12 | something. 13 | 14 | With `NEVec`, you're freed from the boilerplate of constantly needing to 15 | check `is_empty()` or pattern matching before proceeding, or erroring if you 16 | can't. So overall, code, type signatures, and logic become cleaner. 17 | 18 | Consider that unlike `Vec`, [`NEVec::first()`] and [`NEVec::last()`] don't 19 | return in `Option`; they always succeed. 20 | 21 | Alongside [`NEVec`](https://docs.rs/nonempty-collections/latest/nonempty_collections/vector/struct.NEVec.html) are its cousins 22 | [`NESlice`](https://docs.rs/nonempty-collections/latest/nonempty_collections/slice/struct.NESlice.html), [`NEMap`](https://docs.rs/nonempty-collections/latest/nonempty_collections/map/struct.NEMap.html), and 23 | [`NESet`](https://docs.rs/nonempty-collections/latest/nonempty_collections/set/struct.NESet.html), which are all guaranteed to contain at least 24 | one item. 25 | 26 | ## Examples 27 | 28 | The simplest way to construct these non-empty collections is via their 29 | macros: [`nev!`], [`nes!`], and [`nem!`]: 30 | 31 | ```rust 32 | use nonempty_collections::*; 33 | 34 | let v: NEVec = nev![1, 2, 3]; 35 | let s: NESet = nes![1, 2, 2, 3]; // 1 2 3 36 | let m: NEMap<&str, bool> = nem!["a" => true, "b" => false]; 37 | assert_eq!(&1, v.first()); 38 | assert_eq!(3, s.len().get()); 39 | assert!(m.get("a").unwrap()); 40 | ``` 41 | 42 | Unlike the familiar `vec!` macro, `nev!` and friends require at least one 43 | element: 44 | 45 | ```rust 46 | use nonempty_collections::nev; 47 | 48 | let v = nev![1]; 49 | ``` 50 | 51 | A value must be provided: 52 | 53 | ```rust 54 | let v = nev![]; // Doesn't compile! 55 | ``` 56 | 57 | Like `Vec`, you can also construct a [`NEVec`](https://docs.rs/nonempty-collections/latest/nonempty_collections/vector/struct.NEVec.html) the old 58 | fashioned way with [`NEVec::new()`] or its constructor: 59 | 60 | ```rust 61 | use nonempty_collections::NEVec; 62 | 63 | let mut l = NEVec::try_from_vec(vec![42, 36, 58]).unwrap(); 64 | assert_eq!(&42, l.first()); 65 | 66 | l.push(9001); 67 | assert_eq!(l.last(), &9001); 68 | ``` 69 | 70 | And if necessary, you're free to convert to and from `Vec`: 71 | 72 | ```rust 73 | use nonempty_collections::nev; 74 | use nonempty_collections::NEVec; 75 | 76 | let l: NEVec = nev![42, 36, 58, 9001]; 77 | let v: Vec = l.into(); 78 | assert_eq!(v, vec![42, 36, 58, 9001]); 79 | 80 | let u: Option> = NEVec::try_from_vec(v); 81 | assert_eq!(Some(nev![42, 36, 58, 9001]), u); 82 | ``` 83 | 84 | ## Iterators 85 | 86 | This library extends the notion of non-emptiness to iterators, and provides 87 | the [`NonEmptyIterator`](https://docs.rs/nonempty-collections/latest/nonempty_collections/iter/trait.NonEmptyIterator.html) trait. This has some 88 | interesting consequences: 89 | 90 | - Functions like `map` preserve non-emptiness. 91 | - Functions like `max` always have a result. 92 | - A non-empty iterator chain can be `collect`ed back into a non-empty 93 | structure. 94 | - You can chain many operations together without having to double-check for 95 | emptiness. 96 | 97 | ```rust 98 | use nonempty_collections::*; 99 | 100 | let v: NEVec<_> = nev![1, 2, 3].into_nonempty_iter().map(|n| n + 1).collect(); 101 | assert_eq!(&2, v.first()); 102 | ``` 103 | 104 | Consider also [`IntoIteratorExt::try_into_nonempty_iter`] for converting any 105 | given [`Iterator`] and [`IntoIterator`] into a non-empty one, if it contains 106 | at least one item. 107 | 108 | ## Arrays 109 | 110 | Since fixed-size arrays are by definition already not empty, they aren't 111 | given a special wrapper type like [`NEVec`](https://docs.rs/nonempty-collections/latest/nonempty_collections/vector/struct.NEVec.html). Instead, 112 | we enable them to be easily iterated over in a compatible way: 113 | 114 | ```rust 115 | use nonempty_collections::*; 116 | 117 | let a: [u32; 4] = [1, 2, 3, 4]; 118 | let v: NEVec<_> = a.into_nonempty_iter().map(|n| n + 1).collect(); 119 | assert_eq!(nev![2, 3, 4, 5], v); 120 | ``` 121 | See [`NonEmptyArrayExt`](https://docs.rs/nonempty-collections/latest/nonempty_collections/array/trait.NonEmptyArrayExt.html) for more 122 | conversions. 123 | 124 | ## Caveats 125 | 126 | Since `NEVec`, `NEMap`, and `NESet` must have a least one element, it is not 127 | possible to implement the [`FromIterator`] trait for them. We can't 128 | know, in general, if any given standard-library [`Iterator`] actually 129 | contains something. 130 | 131 | ## Features 132 | 133 | * `serde`: `serde` support. 134 | * `indexmap`: adds [`NEIndexMap`](https://docs.rs/nonempty-collections/latest/nonempty_collections/index_map/struct.NEIndexMap.html) a non-empty [`IndexMap`](https://docs.rs/indexmap/latest/indexmap/). 135 | * `itertools`: adds [`NonEmptyItertools`](https://docs.rs/nonempty-collections/latest/nonempty_collections/itertools/trait.NonEmptyItertools.html) a non-empty variant of [`itertools`](https://docs.rs/itertools/latest/itertools/). 136 | * `either`: adds [`NEEither`](https://docs.rs/nonempty-collections/latest/nonempty_collections/either/enum.NEEither.html) a non-empty variant of `Either` from the [`either` crate](https://docs.rs/either/latest/either/). 137 | 138 | 139 | -------------------------------------------------------------------------------- /benches/vec.rs: -------------------------------------------------------------------------------- 1 | //! Benchmarks for `NEVec` versus `Vec`. 2 | 3 | use divan::black_box; 4 | use divan::Bencher; 5 | use nonempty_collections::IntoIteratorExt; 6 | use nonempty_collections::NEVec; 7 | use nonempty_collections::NonEmptyIterator; 8 | 9 | fn main() { 10 | // Run registered benchmarks. 11 | divan::main(); 12 | } 13 | 14 | const LENS: &[usize] = &[1, 8, 64, 1024]; 15 | const SAMPLE_SIZE: u32 = 10000; 16 | 17 | #[divan::bench(args = LENS, sample_size = SAMPLE_SIZE)] 18 | fn contains_vec(bencher: Bencher, len: usize) { 19 | let vec = (0..len).collect::>(); 20 | bencher.bench(|| black_box(vec.contains(&32))); 21 | } 22 | 23 | #[divan::bench(args = LENS, sample_size = SAMPLE_SIZE)] 24 | fn contains_nevec(bencher: Bencher, len: usize) { 25 | let vec = (0..len) 26 | .try_into_nonempty_iter() 27 | .unwrap() 28 | .collect::>(); 29 | bencher.bench(|| black_box(vec.contains(&32))); 30 | } 31 | 32 | #[divan::bench(args = LENS, sample_size = SAMPLE_SIZE)] 33 | fn map_vec(bencher: Bencher, len: usize) { 34 | let vec = (0..len).collect::>(); 35 | bencher.bench(|| black_box(vec.iter().map(|i| i + 7).collect::>())); 36 | } 37 | 38 | #[divan::bench(args = LENS, sample_size = SAMPLE_SIZE)] 39 | fn map_nevec(bencher: Bencher, len: usize) { 40 | let vec = (0..len) 41 | .try_into_nonempty_iter() 42 | .unwrap() 43 | .collect::>(); 44 | bencher.bench(|| black_box(vec.nonempty_iter().map(|i| i + 7).collect::>())); 45 | } 46 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | set quiet 2 | 3 | rust_nightly_version := `cat rust-toolchain-nightly` 4 | 5 | # Call `fmt`, `lint`, `test`, and `check-readme`. 6 | @default: fmt lint test check-readme 7 | 8 | # Format all Rust code. 9 | fmt: 10 | cargo '+{{rust_nightly_version}}' fmt --all 11 | 12 | # Lint all code. 13 | lint: 14 | cargo '+{{rust_nightly_version}}' fmt -- --check 15 | cargo clippy \ 16 | --workspace \ 17 | --tests \ 18 | --benches \ 19 | --all-targets \ 20 | --all-features \ 21 | --quiet 22 | cargo doc --all --no-deps --document-private-items --all-features --quiet 23 | 24 | # Run all tests. 25 | test: 26 | cargo test --workspace --all-features 27 | 28 | # Install the nightly version needed for `fmt` and `lint`. 29 | install-nightly: 30 | rustup toolchain install '{{rust_nightly_version}}' 31 | 32 | install-cargo-rdme: 33 | cargo install cargo-rdme 34 | 35 | update-readme: 36 | cargo rdme 37 | 38 | check-readme: 39 | cargo rdme --check -------------------------------------------------------------------------------- /rust-toolchain-nightly: -------------------------------------------------------------------------------- 1 | nightly-2025-01-09 2 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | imports_granularity = "Item" 2 | wrap_comments = true 3 | format_code_in_doc_comments = true 4 | normalize_comments = true 5 | normalize_doc_attributes = true 6 | group_imports = "StdExternalCrate" 7 | use_field_init_shorthand = true 8 | -------------------------------------------------------------------------------- /src/array.rs: -------------------------------------------------------------------------------- 1 | //! Extends non-zero length arrays with conversion methods to non-empty 2 | //! collections. 3 | //! 4 | //! Since fixed-size arrays are by definition already not empty, they aren't 5 | //! given a special wrapper type like [`crate::NEVec`]. Instead, we enable them 6 | //! to be easily iterated over in a compatible way: 7 | //! 8 | //! ``` 9 | //! use nonempty_collections::*; 10 | //! 11 | //! let a: [u32; 4] = [1, 2, 3, 4]; 12 | //! let v: NEVec<_> = a.into_nonempty_iter().map(|n| n + 1).collect(); 13 | //! assert_eq!(nev![2, 3, 4, 5], v); 14 | //! ``` 15 | //! 16 | //! See [`NonEmptyArrayExt`] for more conversions. 17 | //! 18 | //! # Caveats 19 | //! 20 | //! These extensions are only provided for arrays up to size 32. 21 | 22 | use core::fmt; 23 | use std::num::NonZeroUsize; 24 | 25 | use crate::impl_nonempty_iter_for_arrays; 26 | use crate::IntoNonEmptyIterator; 27 | use crate::NonEmptyIterator; 28 | 29 | /// Provides extension methods for non-empty arrays. 30 | /// 31 | /// # Examples 32 | /// 33 | /// Create a non-empty slice of an array: 34 | /// 35 | /// ``` 36 | /// # use nonempty_collections::*; 37 | /// assert_eq!( 38 | /// NESlice::try_from_slice(&[1, 2]), 39 | /// Some([1, 2].as_nonempty_slice()) 40 | /// ); 41 | /// ``` 42 | /// 43 | /// Get the length of an array as a [`NonZeroUsize`]: 44 | /// 45 | /// ``` 46 | /// # use nonempty_collections::NonEmptyArrayExt; 47 | /// # use std::num::NonZeroUsize; 48 | /// assert_eq!(NonZeroUsize::MIN, [1].nonzero_len()); 49 | /// ``` 50 | /// 51 | /// Convert array into a non-empty vec: 52 | /// 53 | /// ``` 54 | /// # use nonempty_collections::*; 55 | /// assert_eq!(nev![4], [4].into_nonempty_vec()); 56 | /// ``` 57 | pub trait NonEmptyArrayExt { 58 | /// Create a `NESlice` that borrows the contents of `self`. 59 | fn as_nonempty_slice(&self) -> crate::NESlice<'_, T>; 60 | 61 | /// Returns the length of this array as a [`NonZeroUsize`]. 62 | fn nonzero_len(&self) -> NonZeroUsize; 63 | 64 | /// Moves `self` into a new [`crate::NEVec`]. 65 | fn into_nonempty_vec(self) -> crate::NEVec; 66 | } 67 | 68 | /// Non-empty iterator for arrays with length > 0. 69 | /// 70 | /// # Examples 71 | /// 72 | /// Use non-zero length arrays anywhere an [`IntoNonEmptyIterator`] is expected. 73 | /// 74 | /// ``` 75 | /// use std::num::NonZeroUsize; 76 | /// 77 | /// use nonempty_collections::*; 78 | /// 79 | /// fn is_one(iter: impl IntoNonEmptyIterator) { 80 | /// assert_eq!(NonZeroUsize::MIN, iter.into_nonempty_iter().count()); 81 | /// } 82 | /// 83 | /// is_one([0]); 84 | /// ``` 85 | /// 86 | /// Only compiles for non-empty arrays: 87 | /// 88 | /// ```compile_fail 89 | /// use nonempty_collections::*; 90 | /// 91 | /// fn is_one(iter: impl IntoNonEmptyIterator) {} 92 | /// 93 | /// is_one([]); // Doesn't compile because it is empty. 94 | /// ``` 95 | #[derive(Clone)] 96 | pub struct ArrayNonEmptyIterator { 97 | iter: core::array::IntoIter, 98 | } 99 | 100 | impl IntoIterator for ArrayNonEmptyIterator { 101 | type Item = T; 102 | 103 | type IntoIter = core::array::IntoIter; 104 | 105 | fn into_iter(self) -> Self::IntoIter { 106 | self.iter 107 | } 108 | } 109 | 110 | impl NonEmptyIterator for ArrayNonEmptyIterator {} 111 | 112 | impl fmt::Debug for ArrayNonEmptyIterator { 113 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 114 | self.iter.fmt(f) 115 | } 116 | } 117 | 118 | // NOTE 2024-04-05 This must never be implemented for 0. 119 | // 120 | // Also, happy birthday Dad. 121 | impl_nonempty_iter_for_arrays!( 122 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 123 | 27, 28, 29, 30, 31, 32 124 | ); 125 | 126 | #[doc(hidden)] 127 | #[macro_export] 128 | macro_rules! impl_nonempty_iter_for_arrays { 129 | ($($i:literal),+ $(,)?) => { 130 | $( 131 | impl IntoNonEmptyIterator for [T; $i] { 132 | type IntoNEIter = ArrayNonEmptyIterator; 133 | 134 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 135 | ArrayNonEmptyIterator { 136 | iter: self.into_iter(), 137 | } 138 | } 139 | } 140 | 141 | impl<'a, T> IntoNonEmptyIterator for &'a [T; $i] { 142 | type IntoNEIter = $crate::slice::Iter<'a,T>; 143 | 144 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 145 | self.as_nonempty_slice().into_nonempty_iter() 146 | } 147 | } 148 | 149 | impl NonEmptyArrayExt for [T; $i] { 150 | fn as_nonempty_slice(&self) -> $crate::NESlice<'_, T> { 151 | // This should never panic because a slice with length > 0 152 | // is non-empty by definition. 153 | $crate::NESlice::try_from_slice(self).unwrap() 154 | } 155 | 156 | fn nonzero_len(&self) -> NonZeroUsize { 157 | // This should be fine because $i is always > 0. 158 | unsafe { NonZeroUsize::new_unchecked($i) } 159 | } 160 | 161 | fn into_nonempty_vec(self) -> $crate::NEVec { 162 | self.into_nonempty_iter().collect() 163 | } 164 | } 165 | )+ 166 | }; 167 | } 168 | 169 | #[cfg(test)] 170 | mod test { 171 | use crate::IntoNonEmptyIterator; 172 | use crate::NonEmptyIterator; 173 | 174 | #[test] 175 | fn test_iter() { 176 | let iter = [1, 2, 3, 4].into_nonempty_iter(); 177 | let (first, rest) = iter.next(); 178 | assert_eq!(1, first); 179 | assert_eq!(vec![2, 3, 4], rest.into_iter().collect::>()); 180 | 181 | let iter = [1].into_nonempty_iter(); 182 | let (first, rest) = iter.next(); 183 | assert_eq!(1, first); 184 | assert_eq!(0, rest.into_iter().count()); 185 | 186 | assert_eq!(33, [1, -2, 33, 4].into_nonempty_iter().max()); 187 | } 188 | 189 | #[test] 190 | fn test_iter_ref() { 191 | let iter = (&[1, 2, 3, 4]).into_nonempty_iter(); 192 | let (first, rest) = iter.next(); 193 | assert_eq!(&1, first); 194 | assert_eq!(vec![&2, &3, &4], rest.into_iter().collect::>()); 195 | 196 | let iter = (&[1]).into_nonempty_iter(); 197 | let (first, rest) = iter.next(); 198 | assert_eq!(&1, first); 199 | assert_eq!(0, rest.into_iter().count()); 200 | 201 | assert_eq!(&33, (&[1, -2, 33, 4]).into_nonempty_iter().max()); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/either.rs: -------------------------------------------------------------------------------- 1 | //! Extension of [`either::Either`] to provide support for [`NonEmptyIterator`]. 2 | //! 3 | //! ``` 4 | //! use nonempty_collections::*; 5 | //! fn get_data(input: usize) -> NEEither<[usize; 1], [usize; 3]> { 6 | //! if input == 0 { 7 | //! NEEither::Left([0]) 8 | //! } else { 9 | //! NEEither::Right([2, 1, 4]) 10 | //! } 11 | //! } 12 | //! 13 | //! assert_eq!( 14 | //! nev![0], 15 | //! get_data(0).into_nonempty_iter().collect::>() 16 | //! ); 17 | //! ``` 18 | 19 | // Implementation note: 20 | // In an ideal world there is no need for `NEEither` and we could just implement 21 | // `NonEmptyIterator` for `Either`. However, the following holds: 22 | // - `NonEmptyIterator` requires an implementation of `IntoIterator` 23 | // - `Either` conditionally implements `Iterator` 24 | // - Rust has blanket implementation `impl IntoIterator for I` 25 | // Therefore we cannot implement (`Into`)`NonEmptyIterator` for `Either` 26 | // except if we add bounds similar to `L: NonEmptyIterator + Iterator` and `R: 27 | // NonEmptyIterator + Iterator`, which our implementations of `NonEmptyIterator` 28 | // don't satisfy as that would break encapsulation. 29 | 30 | use either::Either; 31 | 32 | use crate::IntoNonEmptyIterator; 33 | use crate::NonEmptyIterator; 34 | 35 | /// Non-empty variant of [`either::Either`] that implements 36 | /// [`NonEmptyIterator`]. 37 | #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 38 | pub enum NEEither { 39 | /// A value of type `L`. 40 | Left(L), 41 | /// A value of type `R`. 42 | Right(R), 43 | } 44 | 45 | impl NEEither { 46 | /// Convert the inner value to a `NonEmptyIterator`. 47 | /// 48 | /// This requires the `Left` and `Right` non-empty iterators to have the 49 | /// same item type. 50 | /// 51 | /// ``` 52 | /// use nonempty_collections::*; 53 | /// let left: NEEither<_, NESet> = NEEither::Left(nev![1, 2, 3]); 54 | /// let right: NEEither, _> = NEEither::Right(nes![4]); 55 | /// 56 | /// let combined = left.into_nonempty_iter().chain(right).collect::>(); 57 | /// let expected = nev![1, 2, 3, 4]; 58 | /// assert_eq!(expected, combined); 59 | /// ``` 60 | pub fn into_nonempty_iter(self) -> NEEither 61 | where 62 | L: IntoNonEmptyIterator, 63 | R: IntoNonEmptyIterator, 64 | { 65 | match self { 66 | NEEither::Left(left) => NEEither::Left(left.into_nonempty_iter()), 67 | NEEither::Right(right) => NEEither::Right(right.into_nonempty_iter()), 68 | } 69 | } 70 | } 71 | 72 | impl NonEmptyIterator for NEEither 73 | where 74 | L: NonEmptyIterator + IntoIterator, 75 | R: NonEmptyIterator + IntoIterator, 76 | { 77 | } 78 | 79 | impl IntoIterator for NEEither 80 | where 81 | L: IntoIterator, 82 | R: IntoIterator, 83 | { 84 | type Item = L::Item; 85 | 86 | type IntoIter = Either; 87 | 88 | fn into_iter(self) -> Self::IntoIter { 89 | match self { 90 | NEEither::Left(left) => Either::Left(left.into_iter()), 91 | NEEither::Right(right) => Either::Right(right.into_iter()), 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/index_map.rs: -------------------------------------------------------------------------------- 1 | //! [`NEIndexMap`] is a non-empty variant of [`IndexMap`]. 2 | //! 3 | //! Unlike `HashMap` and [`crate::NEMap`], these feature a predictable iteration 4 | //! order. 5 | 6 | use std::fmt; 7 | use std::fmt::Debug; 8 | use std::fmt::Formatter; 9 | use std::hash::BuildHasher; 10 | use std::hash::Hash; 11 | use std::num::NonZeroUsize; 12 | 13 | use indexmap::indexmap; 14 | use indexmap::Equivalent; 15 | use indexmap::IndexMap; 16 | 17 | use crate::FromNonEmptyIterator; 18 | use crate::IntoNonEmptyIterator; 19 | use crate::NonEmptyIterator; 20 | 21 | /// Short-hand for constructing [`NEIndexMap`] values. 22 | /// 23 | /// ``` 24 | /// use nonempty_collections::ne_indexmap; 25 | /// 26 | /// let m = ne_indexmap! {"elves" => 3000, "orcs" => 10000}; 27 | /// assert_eq!(2, m.len().get()); 28 | /// ``` 29 | #[macro_export] 30 | macro_rules! ne_indexmap { 31 | ($hk:expr => $hv:expr, $( $xk:expr => $xv:expr,)+) => { $crate::ne_indexmap!{$hk => $hv, $($xk => $xv),+} }; 32 | ($hk:expr => $hv:expr, $( $xk:expr => $xv:expr ),*) => {{ 33 | const CAP: core::num::NonZeroUsize = core::num::NonZeroUsize::MIN.saturating_add(<[()]>::len(&[$({ stringify!($xk); }),*])); 34 | let mut map = $crate::index_map::NEIndexMap::with_capacity(CAP, $hk, $hv); 35 | $( map.insert($xk, $xv); )* 36 | map 37 | }}; 38 | ($hk:expr => $hv:expr) => { 39 | $crate::index_map::NEIndexMap::new($hk, $hv) 40 | } 41 | } 42 | 43 | /// A non-empty, growable [`IndexMap`]. 44 | /// 45 | /// Unlike `HashMap` and [`crate::NEMap`], these feature a predictable iteration 46 | /// order. 47 | /// 48 | /// ``` 49 | /// use nonempty_collections::*; 50 | /// 51 | /// let m = ne_indexmap! {"Netherlands" => 18, "Canada" => 40}; 52 | /// assert_eq!(2, m.len().get()); 53 | /// ``` 54 | #[derive(Clone)] 55 | pub struct NEIndexMap { 56 | inner: IndexMap, 57 | } 58 | 59 | impl NEIndexMap { 60 | /// Returns the number of elements the map can hold without reallocating. 61 | #[must_use] 62 | pub fn capacity(&self) -> NonZeroUsize { 63 | unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) } 64 | } 65 | 66 | /// Returns a reference to the map's `BuildHasher`. 67 | #[must_use] 68 | pub fn hasher(&self) -> &S { 69 | self.inner.hasher() 70 | } 71 | 72 | /// Returns a regular iterator over the entries in this non-empty index map. 73 | /// 74 | /// For a `NonEmptyIterator` see `Self::nonempty_iter()`. 75 | pub fn iter(&self) -> indexmap::map::Iter<'_, K, V> { 76 | self.inner.iter() 77 | } 78 | 79 | /// Returns a regular mutable iterator over the entries in this non-empty 80 | /// index map. 81 | /// 82 | /// For a `NonEmptyIterator` see `Self::nonempty_iter_mut()`. 83 | pub fn iter_mut(&mut self) -> indexmap::map::IterMut<'_, K, V> { 84 | self.inner.iter_mut() 85 | } 86 | 87 | /// An iterator visiting all elements in their order. 88 | pub fn nonempty_iter(&self) -> Iter<'_, K, V> { 89 | Iter { 90 | iter: self.inner.iter(), 91 | } 92 | } 93 | 94 | /// An iterator visiting all elements in their order. 95 | pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, K, V> { 96 | IterMut { 97 | iter: self.inner.iter_mut(), 98 | } 99 | } 100 | 101 | /// An iterator visiting all keys in arbitrary order. The iterator element 102 | /// type is `&'a K`. 103 | /// 104 | /// ``` 105 | /// use nonempty_collections::*; 106 | /// 107 | /// let m = ne_indexmap! {"Duke" => "Leto", "Doctor" => "Yueh", "Planetologist" => "Kynes"}; 108 | /// let v = m.keys().collect::>(); 109 | /// assert_eq!(nev![&"Duke", &"Doctor", &"Planetologist"], v); 110 | /// ``` 111 | pub fn keys(&self) -> Keys<'_, K, V> { 112 | Keys { 113 | inner: self.inner.keys(), 114 | } 115 | } 116 | 117 | /// Returns the number of elements in the map. Always 1 or more. 118 | /// ``` 119 | /// use nonempty_collections::*; 120 | /// 121 | /// let m = ne_indexmap! {"a" => 1, "b" => 2}; 122 | /// assert_eq!(2, m.len().get()); 123 | /// ``` 124 | #[must_use] 125 | pub fn len(&self) -> NonZeroUsize { 126 | unsafe { NonZeroUsize::new_unchecked(self.inner.len()) } 127 | } 128 | 129 | /// A `NEIndexMap` is never empty. 130 | #[deprecated(note = "A NEIndexMap is never empty.")] 131 | #[must_use] 132 | pub const fn is_empty(&self) -> bool { 133 | false 134 | } 135 | 136 | /// An iterator visiting all values in order. 137 | /// 138 | /// ``` 139 | /// use nonempty_collections::*; 140 | /// 141 | /// let m = ne_indexmap!["Caladan" => "Atreides", "Giedi Prime" => "Harkonnen", "Kaitain" => "Corrino"]; 142 | /// assert_eq!(vec![&"Atreides", &"Harkonnen", &"Corrino"], m.values().collect::>()); 143 | /// ``` 144 | pub fn values(&self) -> Values<'_, K, V> { 145 | Values { 146 | inner: self.inner.values(), 147 | } 148 | } 149 | 150 | /// Return an iterator visiting all mutable values in order. 151 | /// 152 | /// ``` 153 | /// use nonempty_collections::*; 154 | /// 155 | /// let mut m = ne_indexmap![0 => "Fremen".to_string(), 1 => "Crysknife".to_string(), 2 => "Water of Life".to_string()]; 156 | /// m.values_mut().into_iter().for_each(|v| v.truncate(3)); 157 | /// 158 | /// assert_eq!(vec![&mut "Fre".to_string(), &mut "Cry".to_string(),&mut "Wat".to_string()], m.values_mut().collect::>()); 159 | /// ``` 160 | pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { 161 | ValuesMut { 162 | inner: self.inner.values_mut(), 163 | } 164 | } 165 | 166 | /// Get the first element. Never fails. 167 | #[allow(clippy::missing_panics_doc)] // the invariant of NEIndexMap is that its non-empty 168 | #[must_use] 169 | pub fn first(&self) -> (&K, &V) { 170 | self.inner.first().unwrap() 171 | } 172 | 173 | /// Get the last element. Never fails. 174 | #[allow(clippy::missing_panics_doc)] // the invariant of NEIndexMap is that its non-empty 175 | #[must_use] 176 | pub fn last(&self) -> (&K, &V) { 177 | self.inner.last().unwrap() 178 | } 179 | } 180 | 181 | impl Debug for NEIndexMap { 182 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 183 | f.debug_map().entries(self.nonempty_iter()).finish() 184 | } 185 | } 186 | 187 | impl NEIndexMap 188 | where 189 | K: Eq + Hash, 190 | { 191 | /// Creates a new `NEIndexMap` with a single element. 192 | #[must_use] 193 | pub fn new(k: K, v: V) -> Self { 194 | Self { 195 | inner: indexmap! {k => v}, 196 | } 197 | } 198 | 199 | /// Creates a new `NEIndexMap` with a single element and specified 200 | /// heap capacity. 201 | #[must_use] 202 | pub fn with_capacity(capacity: NonZeroUsize, k: K, v: V) -> NEIndexMap { 203 | let mut inner = IndexMap::with_capacity(capacity.get()); 204 | inner.insert(k, v); 205 | Self { inner } 206 | } 207 | } 208 | 209 | impl NEIndexMap 210 | where 211 | K: Eq + Hash, 212 | S: BuildHasher, 213 | { 214 | /// Attempt a conversion from [`IndexMap`], consuming the given `IndexMap`. 215 | /// Will return `None` if the `IndexMap` is empty. 216 | /// 217 | /// ``` 218 | /// use indexmap::*; 219 | /// use nonempty_collections::*; 220 | /// 221 | /// assert_eq!( 222 | /// Some(ne_indexmap! {"a" => 1, "b" => 2}), 223 | /// NEIndexMap::try_from_map(indexmap! {"a" => 1, "b" => 2}) 224 | /// ); 225 | /// let m: IndexMap<(), ()> = indexmap! {}; 226 | /// assert_eq!(None, NEIndexMap::try_from_map(m)); 227 | /// ``` 228 | #[must_use] 229 | pub fn try_from_map(map: IndexMap) -> Option { 230 | if map.is_empty() { 231 | None 232 | } else { 233 | Some(Self { inner: map }) 234 | } 235 | } 236 | 237 | /// Returns true if the map contains a value. 238 | /// 239 | /// ``` 240 | /// use nonempty_collections::*; 241 | /// 242 | /// let m = ne_indexmap! {"Paul" => ()}; 243 | /// assert!(m.contains_key("Paul")); 244 | /// assert!(!m.contains_key("Atreides")); 245 | /// ``` 246 | #[must_use] 247 | pub fn contains_key(&self, k: &Q) -> bool 248 | where 249 | Q: Hash + Equivalent + ?Sized, 250 | { 251 | self.inner.contains_key(k) 252 | } 253 | 254 | /// Return a reference to the value stored for `key`, if it is present, 255 | /// else `None`. 256 | /// 257 | /// ``` 258 | /// use nonempty_collections::*; 259 | /// 260 | /// let m = ne_indexmap! {"Arrakis" => 3}; 261 | /// assert_eq!(Some(&3), m.get("Arrakis")); 262 | /// assert_eq!(None, m.get("Caladan")); 263 | /// ``` 264 | #[must_use] 265 | pub fn get(&self, k: &Q) -> Option<&V> 266 | where 267 | Q: Hash + Equivalent + ?Sized, 268 | { 269 | self.inner.get(k) 270 | } 271 | 272 | /// Return references to the key-value pair stored for `key`, 273 | /// if it is present, else `None`. 274 | /// 275 | /// ``` 276 | /// use nonempty_collections::*; 277 | /// 278 | /// let m = ne_indexmap! {"Year" => 1963, "Pages" => 896}; 279 | /// assert_eq!(Some((&"Year", &1963)), m.get_key_value(&"Year")); 280 | /// assert_eq!(Some((&"Pages", &896)), m.get_key_value(&"Pages")); 281 | /// assert_eq!(None, m.get_key_value(&"Title")); 282 | /// ``` 283 | #[must_use] 284 | pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> 285 | where 286 | Q: Hash + Equivalent + ?Sized, 287 | { 288 | self.inner.get_key_value(key) 289 | } 290 | 291 | /// Return a mutable reference to the value stored for `key`, if it is 292 | /// present, else `None`. 293 | /// 294 | /// ``` 295 | /// use nonempty_collections::*; 296 | /// 297 | /// let mut m = ne_indexmap! {"Mentat" => 3, "Bene Gesserit" => 14}; 298 | /// let v = m.get_mut(&"Mentat"); 299 | /// assert_eq!(Some(&mut 3), v); 300 | /// *v.unwrap() += 1; 301 | /// assert_eq!(Some(&mut 4), m.get_mut(&"Mentat")); 302 | /// 303 | /// let v = m.get_mut(&"Bene Gesserit"); 304 | /// assert_eq!(Some(&mut 14), v); 305 | /// *v.unwrap() -= 1; 306 | /// assert_eq!(Some(&mut 13), m.get_mut(&"Bene Gesserit")); 307 | /// 308 | /// assert_eq!(None, m.get_mut(&"Sandworm")); 309 | /// ``` 310 | pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> 311 | where 312 | Q: Hash + Equivalent + ?Sized, 313 | { 314 | self.inner.get_mut(key) 315 | } 316 | 317 | /// Return item index, if it exists in the map. 318 | /// 319 | /// ``` 320 | /// use nonempty_collections::*; 321 | /// let m = ne_indexmap! {"Title" => "Dune", "Author" => "Frank Herbert", "Language" => "English"}; 322 | /// 323 | /// assert_eq!(Some(0), m.get_index_of(&"Title")); 324 | /// assert_eq!(Some(1), m.get_index_of(&"Author")); 325 | /// assert_eq!(None, m.get_index_of(&"Genre")); 326 | /// ```` 327 | #[must_use] 328 | pub fn get_index_of(&self, key: &Q) -> Option 329 | where 330 | Q: Hash + Equivalent + ?Sized, 331 | { 332 | self.inner.get_index_of(key) 333 | } 334 | 335 | /// Insert a key-value pair into the map. 336 | /// 337 | /// If an equivalent key already exists in the map: the key remains and 338 | /// retains in its place in the order, its corresponding value is updated 339 | /// with `value`, and the older value is returned inside `Some(_)`. 340 | /// 341 | /// If no equivalent key existed in the map: the new key-value pair is 342 | /// inserted, last in order, and `None` is returned. 343 | /// ``` 344 | /// use nonempty_collections::*; 345 | /// 346 | /// let mut m = ne_indexmap! {"Duke" => "Leto", "Doctor" => "Yueh"}; 347 | /// assert_eq!(None, m.insert("Lady", "Jessica")); 348 | /// assert_eq!( 349 | /// vec!["Duke", "Doctor", "Lady"], 350 | /// m.keys().copied().collect::>() 351 | /// ); 352 | /// 353 | /// // Spoiler alert: there is a different duke at some point 354 | /// assert_eq!(Some("Leto"), m.insert("Duke", "Paul")); 355 | /// assert_eq!( 356 | /// vec!["Paul", "Yueh", "Jessica"], 357 | /// m.values().copied().collect::>() 358 | /// ); 359 | /// ``` 360 | pub fn insert(&mut self, k: K, v: V) -> Option { 361 | self.inner.insert(k, v) 362 | } 363 | 364 | /// Shrink the capacity of the map as much as possible. 365 | pub fn shrink_to_fit(&mut self) { 366 | self.inner.shrink_to_fit(); 367 | } 368 | 369 | /// Creates a new `NEIndexMap` with a single element and specified 370 | /// heap capacity and hasher. 371 | #[must_use] 372 | pub fn with_capacity_and_hasher( 373 | capacity: NonZeroUsize, 374 | hasher: S, 375 | k: K, 376 | v: V, 377 | ) -> NEIndexMap { 378 | let mut inner = IndexMap::with_capacity_and_hasher(capacity.get(), hasher); 379 | inner.insert(k, v); 380 | Self { inner } 381 | } 382 | 383 | /// See [`IndexMap::with_hasher`]. 384 | #[must_use] 385 | pub fn with_hasher(hasher: S, k: K, v: V) -> NEIndexMap { 386 | let mut inner = IndexMap::with_hasher(hasher); 387 | inner.insert(k, v); 388 | Self { inner } 389 | } 390 | 391 | /// Swaps the position of two key-value pairs in the map. 392 | /// 393 | /// # Panics 394 | /// If `a` or `b` are out of bounds. 395 | pub fn swap_indices(&mut self, a: usize, b: usize) { 396 | self.inner.swap_indices(a, b); 397 | } 398 | } 399 | 400 | impl PartialEq for NEIndexMap 401 | where 402 | K: Eq + Hash, 403 | V: Eq, 404 | S: BuildHasher, 405 | { 406 | fn eq(&self, other: &Self) -> bool { 407 | self.inner.eq(&other.inner) 408 | } 409 | } 410 | 411 | impl Eq for NEIndexMap 412 | where 413 | K: Eq + Hash, 414 | V: Eq, 415 | S: BuildHasher, 416 | { 417 | } 418 | 419 | impl From> for IndexMap 420 | where 421 | K: Eq + Hash, 422 | S: BuildHasher, 423 | { 424 | /// ``` 425 | /// use indexmap::IndexMap; 426 | /// use nonempty_collections::*; 427 | /// 428 | /// let m: IndexMap<&str, usize> = ne_indexmap! {"population" => 1000}.into(); 429 | /// assert!(m.contains_key("population")); 430 | /// ``` 431 | fn from(m: NEIndexMap) -> Self { 432 | m.inner 433 | } 434 | } 435 | 436 | impl IntoNonEmptyIterator for NEIndexMap { 437 | type IntoNEIter = IntoIter; 438 | 439 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 440 | IntoIter { 441 | iter: self.inner.into_iter(), 442 | } 443 | } 444 | } 445 | 446 | impl<'a, K, V, S> IntoNonEmptyIterator for &'a NEIndexMap { 447 | type IntoNEIter = Iter<'a, K, V>; 448 | 449 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 450 | self.nonempty_iter() 451 | } 452 | } 453 | 454 | impl IntoIterator for NEIndexMap { 455 | type Item = (K, V); 456 | 457 | type IntoIter = indexmap::map::IntoIter; 458 | 459 | fn into_iter(self) -> Self::IntoIter { 460 | self.inner.into_iter() 461 | } 462 | } 463 | 464 | impl<'a, K, V, S> IntoIterator for &'a NEIndexMap { 465 | type Item = (&'a K, &'a V); 466 | 467 | type IntoIter = indexmap::map::Iter<'a, K, V>; 468 | 469 | fn into_iter(self) -> Self::IntoIter { 470 | self.iter() 471 | } 472 | } 473 | 474 | impl<'a, K, V, S> IntoIterator for &'a mut NEIndexMap { 475 | type Item = (&'a K, &'a mut V); 476 | 477 | type IntoIter = indexmap::map::IterMut<'a, K, V>; 478 | 479 | fn into_iter(self) -> Self::IntoIter { 480 | self.iter_mut() 481 | } 482 | } 483 | 484 | /// ``` 485 | /// use nonempty_collections::*; 486 | /// 487 | /// let v = nev![('a', 1), ('b', 2), ('c', 3), ('a', 4)]; 488 | /// let m0 = v.into_nonempty_iter().collect::>(); 489 | /// let m1 = ne_indexmap! {'a' => 4, 'b' => 2, 'c' => 3}; 490 | /// assert_eq!(m0, m1); 491 | /// ``` 492 | impl FromNonEmptyIterator<(K, V)> for NEIndexMap 493 | where 494 | K: Eq + Hash, 495 | S: BuildHasher + Default, 496 | { 497 | fn from_nonempty_iter(iter: I) -> Self 498 | where 499 | I: IntoNonEmptyIterator, 500 | { 501 | Self { 502 | inner: iter.into_nonempty_iter().into_iter().collect(), 503 | } 504 | } 505 | } 506 | 507 | impl std::ops::Index for NEIndexMap { 508 | type Output = V; 509 | 510 | fn index(&self, index: usize) -> &V { 511 | self.inner.index(index) 512 | } 513 | } 514 | 515 | /// A non-empty iterator over the entries of an [`NEIndexMap`]. 516 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 517 | pub struct Iter<'a, K: 'a, V: 'a> { 518 | iter: indexmap::map::Iter<'a, K, V>, 519 | } 520 | 521 | impl NonEmptyIterator for Iter<'_, K, V> {} 522 | 523 | impl<'a, K, V> IntoIterator for Iter<'a, K, V> { 524 | type Item = (&'a K, &'a V); 525 | 526 | type IntoIter = indexmap::map::Iter<'a, K, V>; 527 | 528 | fn into_iter(self) -> Self::IntoIter { 529 | self.iter 530 | } 531 | } 532 | 533 | // FIXME: Remove in favor of `#[derive(Clone)]` (see https://github.com/rust-lang/rust/issues/26925 for more info) 534 | impl Clone for Iter<'_, K, V> { 535 | fn clone(&self) -> Self { 536 | Iter { 537 | iter: self.iter.clone(), 538 | } 539 | } 540 | } 541 | 542 | impl Debug for Iter<'_, K, V> { 543 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 544 | f.debug_list().entries(self.clone()).finish() 545 | } 546 | } 547 | 548 | /// A mutable non-empty iterator over the entries of an [`NEIndexMap`]. 549 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 550 | pub struct IterMut<'a, K: 'a, V: 'a> { 551 | iter: indexmap::map::IterMut<'a, K, V>, 552 | } 553 | 554 | impl NonEmptyIterator for IterMut<'_, K, V> {} 555 | 556 | impl<'a, K, V> IntoIterator for IterMut<'a, K, V> { 557 | type Item = (&'a K, &'a mut V); 558 | 559 | type IntoIter = indexmap::map::IterMut<'a, K, V>; 560 | 561 | fn into_iter(self) -> Self::IntoIter { 562 | self.iter 563 | } 564 | } 565 | 566 | impl Debug for IterMut<'_, K, V> { 567 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 568 | self.iter.fmt(f) 569 | } 570 | } 571 | 572 | /// A non-empty iterator over the entries of an [`NEIndexMap`]. 573 | pub struct IntoIter { 574 | iter: indexmap::map::IntoIter, 575 | } 576 | 577 | impl NonEmptyIterator for IntoIter {} 578 | 579 | impl IntoIterator for IntoIter { 580 | type Item = (K, V); 581 | 582 | type IntoIter = indexmap::map::IntoIter; 583 | 584 | fn into_iter(self) -> Self::IntoIter { 585 | self.iter 586 | } 587 | } 588 | 589 | impl Debug for IntoIter { 590 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 591 | self.iter.fmt(f) 592 | } 593 | } 594 | 595 | /// A non-empty iterator over the keys of an [`NEIndexMap`]. 596 | /// 597 | /// ``` 598 | /// use nonempty_collections::*; 599 | /// 600 | /// let m = ne_indexmap! {"elves" => 3000, "orcs" => 10000}; 601 | /// let v = m.keys().copied().collect::>(); 602 | /// assert_eq!(nev!["elves", "orcs"], v); 603 | /// ``` 604 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 605 | pub struct Keys<'a, K: 'a, V: 'a> { 606 | inner: indexmap::map::Keys<'a, K, V>, 607 | } 608 | 609 | impl NonEmptyIterator for Keys<'_, K, V> {} 610 | 611 | impl<'a, K, V> IntoIterator for Keys<'a, K, V> { 612 | type Item = &'a K; 613 | 614 | type IntoIter = indexmap::map::Keys<'a, K, V>; 615 | 616 | fn into_iter(self) -> Self::IntoIter { 617 | self.inner 618 | } 619 | } 620 | 621 | // FIXME: Remove in favor of `#[derive(Clone)]` (see https://github.com/rust-lang/rust/issues/26925 for more info) 622 | impl Clone for Keys<'_, K, V> { 623 | fn clone(&self) -> Self { 624 | Keys { 625 | inner: self.inner.clone(), 626 | } 627 | } 628 | } 629 | 630 | impl Debug for Keys<'_, K, V> { 631 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 632 | f.debug_list().entries(self.clone()).finish() 633 | } 634 | } 635 | 636 | /// A non-empty iterator over the values of an [`NEIndexMap`]. 637 | /// 638 | /// ``` 639 | /// use nonempty_collections::*; 640 | /// 641 | /// let m = ne_indexmap! {"elves" => 3000, "orcs" => 10000}; 642 | /// let mut v = m.values().copied().collect::>(); 643 | /// v.sort(); 644 | /// assert_eq!(nev![3000, 10000], v); 645 | /// ``` 646 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 647 | pub struct Values<'a, K: 'a, V: 'a> { 648 | inner: indexmap::map::Values<'a, K, V>, 649 | } 650 | 651 | impl NonEmptyIterator for Values<'_, K, V> {} 652 | 653 | impl<'a, K, V> IntoIterator for Values<'a, K, V> { 654 | type Item = &'a V; 655 | 656 | type IntoIter = indexmap::map::Values<'a, K, V>; 657 | 658 | fn into_iter(self) -> Self::IntoIter { 659 | self.inner 660 | } 661 | } 662 | 663 | // FIXME: Remove in favor of `#[derive(Clone)]` (see https://github.com/rust-lang/rust/issues/26925 for more info) 664 | impl Clone for Values<'_, K, V> { 665 | fn clone(&self) -> Self { 666 | Values { 667 | inner: self.inner.clone(), 668 | } 669 | } 670 | } 671 | 672 | impl Debug for Values<'_, K, V> { 673 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 674 | f.debug_list().entries(self.clone()).finish() 675 | } 676 | } 677 | 678 | /// A non-empty iterator over the mutable values of an [`NEIndexMap`]. 679 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 680 | pub struct ValuesMut<'a, K: 'a, V: 'a> { 681 | inner: indexmap::map::ValuesMut<'a, K, V>, 682 | } 683 | 684 | impl NonEmptyIterator for ValuesMut<'_, K, V> {} 685 | 686 | impl<'a, K, V> IntoIterator for ValuesMut<'a, K, V> { 687 | type Item = &'a mut V; 688 | 689 | type IntoIter = indexmap::map::ValuesMut<'a, K, V>; 690 | 691 | fn into_iter(self) -> Self::IntoIter { 692 | self.inner 693 | } 694 | } 695 | 696 | impl Debug for ValuesMut<'_, K, V> { 697 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 698 | self.inner.fmt(f) 699 | } 700 | } 701 | 702 | #[cfg(test)] 703 | mod test { 704 | use super::*; 705 | 706 | #[test] 707 | fn test_swap_indices() { 708 | let mut map = ne_indexmap! { 0 => (), 1 => () }; 709 | assert_eq!(vec![0, 1], map.keys().copied().collect::>()); 710 | map.swap_indices(0, 1); 711 | assert_eq!(vec![1, 0], map.keys().copied().collect::>()); 712 | map.swap_indices(1, 0); 713 | assert_eq!(vec![0, 1], map.keys().copied().collect::>()); 714 | 715 | let mut map = ne_indexmap! { 0 => (), 1 => (), 2 => () }; 716 | assert_eq!(vec![0, 1, 2], map.keys().copied().collect::>()); 717 | map.swap_indices(0, 1); 718 | assert_eq!(vec![1, 0, 2], map.keys().copied().collect::>()); 719 | map.swap_indices(1, 0); 720 | assert_eq!(vec![0, 1, 2], map.keys().copied().collect::>()); 721 | map.swap_indices(0, 2); 722 | assert_eq!(vec![2, 1, 0], map.keys().copied().collect::>()); 723 | map.swap_indices(1, 2); 724 | assert_eq!(vec![2, 0, 1], map.keys().copied().collect::>()); 725 | 726 | let mut map = ne_indexmap! { 0 => (), 1 => (), 2 => (), 3 => (), 4 => (), 5 => () }; 727 | assert_eq!( 728 | vec![0, 1, 2, 3, 4, 5], 729 | map.keys().copied().collect::>() 730 | ); 731 | map.swap_indices(1, 2); 732 | assert_eq!( 733 | vec![0, 2, 1, 3, 4, 5], 734 | map.keys().copied().collect::>() 735 | ); 736 | map.swap_indices(0, 3); 737 | assert_eq!( 738 | vec![3, 2, 1, 0, 4, 5], 739 | map.keys().copied().collect::>() 740 | ); 741 | } 742 | 743 | #[test] 744 | fn debug_impl() { 745 | let expected = format!("{:?}", indexmap! {0 => 10, 1 => 11, 2 => 12}); 746 | let actual = format!("{:?}", ne_indexmap! {0 => 10, 1 => 11, 2 => 12}); 747 | assert_eq!(expected, actual); 748 | } 749 | 750 | #[test] 751 | fn iter_mut() { 752 | let mut v = ne_indexmap! {"a" => 0, "b" => 1, "c" => 2}; 753 | 754 | v.iter_mut().for_each(|(_k, v)| { 755 | *v += 1; 756 | }); 757 | assert_eq!(ne_indexmap! {"a" => 1, "b" => 2, "c" => 3}, v); 758 | 759 | for (_k, v) in &mut v { 760 | *v -= 1; 761 | } 762 | assert_eq!(ne_indexmap! {"a" => 0, "b" => 1, "c" => 2}, v); 763 | } 764 | } 765 | -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | //! Non-empty iterators. 2 | 3 | use std::cell::RefCell; 4 | use std::cmp::Ordering; 5 | use std::collections::HashMap; 6 | use std::collections::HashSet; 7 | use std::hash::BuildHasher; 8 | use std::hash::Hash; 9 | use std::iter::Product; 10 | use std::iter::Sum; 11 | use std::num::NonZeroUsize; 12 | use std::rc::Rc; 13 | use std::result::Result; 14 | 15 | use crate::nev; 16 | use crate::NEVec; 17 | 18 | // Iterator structs which _always_ have something if the source iterator is 19 | // non-empty: 20 | // 21 | // - [x] Chain (if one, the other, or both are nonempty) 22 | // - [x] Cloned 23 | // - [x] Copied 24 | // - [ ] Cycle 25 | // - [x] Enumerate 26 | // - [x] Map 27 | // - [x] Once 28 | // - [ ] Scan 29 | // - [x] Take 30 | // - [x] Zip (if both are nonempty) 31 | 32 | /// Creates an iterator that yields an element exactly once. 33 | /// 34 | /// See also [`std::iter::once`]. 35 | pub fn once(value: T) -> Once { 36 | Once::new(value) 37 | } 38 | 39 | /// An [`Iterator`] that is guaranteed to have at least one item. 40 | /// 41 | /// By implementing `NonEmptyIterator` for a type the implementor is responsible 42 | /// for ensuring that non-emptiness holds. Violating this invariant may lead to 43 | /// panics and/or undefined behavior. 44 | pub trait NonEmptyIterator: IntoIterator { 45 | /// Advances this non-empty iterator, consuming its ownership. Yields the 46 | /// first item and a possibly empty iterator containing the rest of the 47 | /// elements. 48 | #[must_use] 49 | fn next(self) -> (Self::Item, Self::IntoIter) 50 | where 51 | Self: Sized, 52 | { 53 | let mut iter = self.into_iter(); 54 | (iter.next().unwrap(), iter) 55 | } 56 | 57 | /// Creates an iterator which can use the [`peek`] and [`peek_mut`] methods 58 | /// to look at the next element of the iterator without consuming it. See 59 | /// their documentation for more information. 60 | /// 61 | /// Note that the underlying iterator is still advanced when this method is 62 | /// called. In order to retrieve the next element, [`next`] is called on the 63 | /// underlying iterator, hence any side effects (i.e. anything other than 64 | /// fetching the next value) of the [`next`] method will occur. 65 | /// 66 | /// # Examples 67 | /// 68 | /// ``` 69 | /// use nonempty_collections::*; 70 | /// 71 | /// let v = nev![0, 1, 2, 3]; 72 | /// let iter = v.into_nonempty_iter().peekable(); 73 | /// assert_eq!(&0, iter.peek()); 74 | /// ``` 75 | /// 76 | /// [`peek`]: Peekable::peek 77 | /// [`peek_mut`]: Peekable::peek_mut 78 | /// [`next`]: Iterator::next 79 | fn peekable(self) -> Peekable 80 | where 81 | Self: Sized, 82 | { 83 | let mut iter = self.into_iter(); 84 | Peekable { 85 | first: iter.next().unwrap(), 86 | rest: iter, 87 | } 88 | } 89 | 90 | /// Tests if every element of the iterator matches a predicate. 91 | /// 92 | /// Because this function always advances the iterator at least once, the 93 | /// non-empty guarantee is invalidated. Therefore, this function consumes 94 | /// this `NonEmptyIterator`. 95 | /// 96 | /// See also [`Iterator::all`]. 97 | /// 98 | /// # Examples 99 | /// 100 | /// ``` 101 | /// use nonempty_collections::*; 102 | /// 103 | /// let n = nev![2, 2, 2]; 104 | /// assert!(n.nonempty_iter().all(|n| n % 2 == 0)); 105 | /// assert!(n.iter().all(|n| n % 2 == 0)); 106 | /// ``` 107 | #[must_use] 108 | fn all(self, f: F) -> bool 109 | where 110 | Self: Sized, 111 | F: FnMut(Self::Item) -> bool, 112 | { 113 | self.into_iter().all(f) 114 | } 115 | 116 | /// Tests if any element of the iterator matches a predicate. 117 | /// 118 | /// Because this function always advances the iterator at least once, the 119 | /// non-empty guarantee is invalidated. Therefore, this function consumes 120 | /// this `NonEmptyIterator`. 121 | /// 122 | /// See also [`Iterator::any`]. 123 | /// 124 | /// # Examples 125 | /// 126 | /// ``` 127 | /// use nonempty_collections::*; 128 | /// 129 | /// let n = nev![1, 1, 1, 2, 1, 1]; 130 | /// assert!(n.nonempty_iter().any(|n| n % 2 == 0)); 131 | /// assert!(!n.nonempty_iter().any(|n| n % 3 == 0)); 132 | /// ``` 133 | #[must_use] 134 | fn any(self, f: F) -> bool 135 | where 136 | Self: Sized, 137 | F: FnMut(Self::Item) -> bool, 138 | { 139 | self.into_iter().any(f) 140 | } 141 | 142 | /// Takes two iterators and creates a new non-empty iterator over both in 143 | /// sequence. 144 | /// 145 | /// Note that the second iterator need not be empty. 146 | /// 147 | /// See also [`Iterator::chain`]. 148 | /// 149 | /// ``` 150 | /// use nonempty_collections::*; 151 | /// 152 | /// let v = nev![1, 2, 3]; 153 | /// let s = nes![4, 5, 6]; 154 | /// let mut r: Vec<_> = v.into_nonempty_iter().chain(s).collect(); 155 | /// r.sort(); 156 | /// 157 | /// assert_eq!(vec![1, 2, 3, 4, 5, 6], r); 158 | /// ``` 159 | fn chain(self, other: U) -> Chain 160 | where 161 | Self: Sized, 162 | U: IntoIterator, 163 | { 164 | Chain { 165 | inner: self.into_iter().chain(other), 166 | } 167 | } 168 | 169 | /// Creates a non-empty iterator which clones all of its elements. 170 | /// 171 | /// This is useful when you have an iterator over `&T`, but you need an 172 | /// iterator over `T`. 173 | /// 174 | /// See also [`Iterator::cloned`]. 175 | /// 176 | /// ``` 177 | /// use nonempty_collections::NEVec; 178 | /// use nonempty_collections::*; 179 | /// 180 | /// #[derive(Debug, Clone, PartialEq, Eq)] 181 | /// enum Foo { 182 | /// A, 183 | /// B, 184 | /// C, 185 | /// } 186 | /// 187 | /// let v0 = nev![Foo::A, Foo::B, Foo::C]; 188 | /// let v1: NEVec<_> = v0.nonempty_iter().collect(); 189 | /// let v2: NEVec<_> = v0.nonempty_iter().cloned().collect(); 190 | /// 191 | /// assert_eq!(nev![&Foo::A, &Foo::B, &Foo::C], v1); 192 | /// assert_eq!(nev![Foo::A, Foo::B, Foo::C], v2); 193 | /// ``` 194 | fn cloned<'a, T>(self) -> Cloned 195 | where 196 | Self: Sized + NonEmptyIterator, 197 | T: Clone + 'a, 198 | { 199 | Cloned { iter: self } 200 | } 201 | 202 | /// Transforms an iterator into a collection, or some other concrete value. 203 | /// 204 | /// See also [`Iterator::collect`]. 205 | /// 206 | /// ``` 207 | /// use nonempty_collections::*; 208 | /// 209 | /// let n0 = nev![1, 2, 3, 4]; 210 | /// let n1 = n0.into_nonempty_iter().collect(); 211 | /// assert_eq!(nev![1, 2, 3, 4], n1); 212 | /// ``` 213 | #[must_use] 214 | fn collect(self) -> B 215 | where 216 | Self: Sized, 217 | B: FromNonEmptyIterator, 218 | { 219 | FromNonEmptyIterator::from_nonempty_iter(self) 220 | } 221 | 222 | /// Creates a non-empty iterator which copies all of its elements. 223 | /// 224 | /// See also [`Iterator::copied`]. 225 | /// 226 | /// ``` 227 | /// use nonempty_collections::*; 228 | /// 229 | /// let n0 = nev![1, 2, 3, 4]; 230 | /// let n1 = n0.nonempty_iter().copied().collect(); 231 | /// assert_eq!(n0, n1); 232 | /// ``` 233 | fn copied<'a, T>(self) -> Copied 234 | where 235 | Self: Sized + NonEmptyIterator, 236 | T: Copy + 'a, 237 | { 238 | Copied { 239 | iter: self.into_iter().copied(), 240 | } 241 | } 242 | 243 | /// Consumes the non-empty iterator, counting the number of iterations and 244 | /// returning it. 245 | /// 246 | /// See also [`Iterator::count`]. 247 | /// 248 | /// ``` 249 | /// use nonempty_collections::*; 250 | /// 251 | /// let n = nev![1]; 252 | /// assert_eq!(1, n.nonempty_iter().count().get()); 253 | /// 254 | /// let n = nev![1, 2, 3, 4, 5, 6]; 255 | /// assert_eq!(6, n.nonempty_iter().count().get()); 256 | /// ```` 257 | #[must_use] 258 | fn count(self) -> NonZeroUsize 259 | where 260 | Self: Sized, 261 | { 262 | unsafe { NonZeroUsize::new_unchecked(self.into_iter().count()) } 263 | } 264 | 265 | /// Creates a non-empty iterator which gives the current iteration count as 266 | /// well as the next value. 267 | /// 268 | /// See also [`Iterator::enumerate`]. 269 | /// 270 | /// ``` 271 | /// use nonempty_collections::*; 272 | /// 273 | /// let s = nes!["Doriath", "Gondolin", "Nargothrond"]; 274 | /// let total: usize = s.nonempty_iter().enumerate().map(|(c, _)| c).sum(); 275 | /// assert_eq!(3, total); 276 | /// ``` 277 | fn enumerate(self) -> Enumerate 278 | where 279 | Self: Sized, 280 | { 281 | Enumerate { iter: self } 282 | } 283 | 284 | /// Creates an iterator which uses a closure to determine if an element 285 | /// should be yielded. 286 | /// 287 | /// **Note:** The iterator returned by this method is **not** a 288 | /// `NonEmptyIterator`, since there is never a guarantee that any element 289 | /// will pass the predicate. 290 | /// 291 | /// See also [`Iterator::filter`]. 292 | /// 293 | /// ``` 294 | /// use nonempty_collections::*; 295 | /// 296 | /// let n = nev![1, 2, 3, 4, 5, 6]; 297 | /// let v: Vec<_> = n 298 | /// .nonempty_iter() 299 | /// .map(|x| x * 2) 300 | /// .filter(|&x| x % 3 == 0) 301 | /// .collect(); 302 | /// assert_eq!(vec![6, 12], v); 303 | /// ``` 304 | fn filter

(self, predicate: P) -> std::iter::Filter<::IntoIter, P> 305 | where 306 | Self: Sized, 307 | P: FnMut(&::Item) -> bool, 308 | { 309 | self.into_iter().filter(predicate) 310 | } 311 | 312 | /// Creates an iterator that both filters and maps. 313 | /// 314 | /// **Note:** The iterator returned by this method is **not** a 315 | /// `NonEmptyIterator`, since there is never a guarantee that any element 316 | /// will yield `Some` from the given function. 317 | /// 318 | /// See also [`Iterator::filter_map`]. 319 | /// 320 | /// ``` 321 | /// use nonempty_collections::*; 322 | /// 323 | /// let v = nev!["Frodo", "Sam", "", "Peregrin", "Meriadoc"]; 324 | /// let firsts: Vec = v 325 | /// .into_nonempty_iter() 326 | /// .filter_map(|s| s.chars().next()) 327 | /// .collect(); 328 | /// assert_eq!(vec!['F', 'S', 'P', 'M'], firsts); 329 | /// ``` 330 | fn filter_map(self, f: F) -> std::iter::FilterMap<::IntoIter, F> 331 | where 332 | Self: Sized, 333 | F: FnMut(::Item) -> Option, 334 | { 335 | self.into_iter().filter_map(f) 336 | } 337 | 338 | /// Searches for an element of an iterator that satisfies a predicate. 339 | /// 340 | /// Because this function always advances the iterator at least once, the 341 | /// non-empty guarantee is invalidated. Therefore, this function consumes 342 | /// this `NonEmptyIterator`. 343 | /// 344 | /// See also [`Iterator::find`]. 345 | /// 346 | /// # Examples 347 | /// 348 | /// ``` 349 | /// use nonempty_collections::*; 350 | /// 351 | /// let n = nev![1, 3, 5, 7, 9, 10]; 352 | /// assert_eq!(Some(&10), n.iter().find(|n| *n % 2 == 0)); 353 | /// assert_eq!(None, n.iter().find(|n| **n > 10)); 354 | /// ``` 355 | #[must_use] 356 | fn find

(self, predicate: P) -> Option 357 | where 358 | Self: Sized, 359 | P: FnMut(&Self::Item) -> bool, 360 | { 361 | self.into_iter().find(predicate) 362 | } 363 | 364 | /// Creates an iterator that works like `map`, but flattens nested, 365 | /// non-empty structure. 366 | /// 367 | /// See also [`Iterator::flat_map`]. 368 | /// 369 | /// ``` 370 | /// use nonempty_collections::*; 371 | /// 372 | /// let v = nev![1, 2, 3]; 373 | /// let r = v.into_nonempty_iter().flat_map(|n| nev![n]).collect(); 374 | /// assert_eq!(nev![1, 2, 3], r); 375 | /// ``` 376 | #[inline] 377 | fn flat_map(self, f: F) -> FlatMap 378 | where 379 | Self: Sized, 380 | F: FnMut(Self::Item) -> U, 381 | U: IntoNonEmptyIterator, 382 | { 383 | FlatMap { 384 | inner: self.into_iter().flat_map(f), 385 | } 386 | } 387 | 388 | // fn flatten(self) -> FlatMap 389 | // where 390 | // Self: Sized, 391 | // Self::Item: IntoNonEmptyIterator, 392 | // V: NonEmptyIterator, 393 | // { 394 | // self.flat_map(|ne| ne) 395 | // } 396 | 397 | /// Folds every element into an accumulator by applying an operation, 398 | /// returning the final result. 399 | /// 400 | /// See also [`Iterator::fold`]. 401 | /// 402 | /// ``` 403 | /// use nonempty_collections::*; 404 | /// 405 | /// let n = nev![1, 2, 3, 4]; 406 | /// let r = n.into_nonempty_iter().fold(0, |acc, x| acc + x); 407 | /// assert_eq!(10, r); 408 | /// ``` 409 | #[must_use] 410 | fn fold(self, init: B, f: F) -> B 411 | where 412 | Self: Sized, 413 | F: FnMut(B, Self::Item) -> B, 414 | { 415 | self.into_iter().fold(init, f) 416 | } 417 | 418 | /// Group the non-empty input stream into concrete, non-empty subsections 419 | /// via a given function. The cutoff criterion is whether the return value 420 | /// of `f` changes between two consecutive elements. 421 | /// 422 | /// ``` 423 | /// use nonempty_collections::*; 424 | /// 425 | /// let n = nev![1, 1, 2, 3, 3]; 426 | /// let r: NEVec<_> = n.into_nonempty_iter().group_by(|n| *n).collect(); 427 | /// assert_eq!(r, nev![nev![1, 1], nev![2], nev![3, 3]]); 428 | /// 429 | /// let n = nev![2, 4, 6, 7, 9, 1, 2, 4, 6, 3]; 430 | /// let r: NEVec<_> = n.into_nonempty_iter().group_by(|n| n % 2 == 0).collect(); 431 | /// assert_eq!( 432 | /// r, 433 | /// nev![nev![2, 4, 6], nev![7, 9, 1], nev![2, 4, 6], nev![3]] 434 | /// ); 435 | /// ``` 436 | fn group_by(self, f: F) -> NEGroupBy 437 | where 438 | Self: Sized, 439 | F: FnMut(&Self::Item) -> K, 440 | K: PartialEq, 441 | { 442 | NEGroupBy { iter: self, f } 443 | } 444 | 445 | /// Takes a closure and creates a non-empty iterator which calls that 446 | /// closure on each element. 447 | /// 448 | /// If `self` is a `NonEmptyIterator`, then so is [`Map`]. 449 | /// 450 | /// See also [`Iterator::map`]. 451 | /// 452 | /// ``` 453 | /// use nonempty_collections::NEVec; 454 | /// use nonempty_collections::*; 455 | /// 456 | /// let s = nes![1, 2, 3]; 457 | /// let mut v: NEVec<_> = s.nonempty_iter().map(|n| n * 2).collect(); 458 | /// v.sort(); 459 | /// assert_eq!(nev![2, 4, 6], v); 460 | /// ``` 461 | #[inline] 462 | fn map(self, f: F) -> Map 463 | where 464 | Self: Sized, 465 | F: FnMut(Self::Item) -> U, 466 | { 467 | Map { 468 | iter: self.into_iter().map(f), 469 | } 470 | } 471 | 472 | /// Returns the maximum element of a non-empty iterator. 473 | /// 474 | /// Unlike [`Iterator::max`], this always yields a value. 475 | /// 476 | /// ``` 477 | /// use nonempty_collections::*; 478 | /// 479 | /// let v = nev![1, 1000, 2, 3]; 480 | /// assert_eq!(1000, v.into_nonempty_iter().max()); 481 | /// ``` 482 | #[must_use] 483 | fn max(self) -> Self::Item 484 | where 485 | Self: Sized, 486 | Self::Item: Ord, 487 | { 488 | self.max_by(Ord::cmp) 489 | } 490 | 491 | /// Returns the element that gives the maximum value with respect to the 492 | /// given comparison function. 493 | /// 494 | /// Unlike [`Iterator::max_by`], this always yields a value. 495 | #[must_use] 496 | fn max_by(self, compare: F) -> Self::Item 497 | where 498 | Self: Sized, 499 | F: Fn(&Self::Item, &Self::Item) -> Ordering, 500 | { 501 | let (first, iter) = self.next(); 502 | 503 | iter.into_iter() 504 | .fold(first, |acc, item| match compare(&acc, &item) { 505 | Ordering::Less => item, 506 | _ => acc, 507 | }) 508 | } 509 | 510 | /// Returns the element that gives the maximum value from the 511 | /// specified function. 512 | /// 513 | /// There are two differences with [`Iterator::max_by_key`]: 514 | /// - this function always yields a value while [`Iterator::max_by_key`] 515 | /// yields an `Option`. 516 | /// - if several elements are equally maximum, the *first* element is 517 | /// returned (unlike [`Iterator::max_by_key`] which returns the last 518 | /// element). 519 | /// 520 | /// # Examples 521 | /// 522 | /// ``` 523 | /// use nonempty_collections::*; 524 | /// let max = nev!["hi", "hey", "rust", "yolo"] 525 | /// .into_nonempty_iter() 526 | /// .max_by_key(|item| item.len()); 527 | /// assert_eq!("rust", max); 528 | /// ``` 529 | #[must_use] 530 | fn max_by_key(self, mut key: F) -> Self::Item 531 | where 532 | Self: Sized, 533 | B: Ord, 534 | F: FnMut(&Self::Item) -> B, 535 | { 536 | self.map(|item| (key(&item), item)) 537 | .max_by(|(left_key, _), (right_key, _)| left_key.cmp(right_key)) 538 | .1 539 | } 540 | 541 | /// Returns the minimum element of a non-empty iterator. 542 | /// 543 | /// Unlike [`Iterator::min`], this always yields a value. 544 | /// 545 | /// ``` 546 | /// use nonempty_collections::*; 547 | /// 548 | /// let v = nev![1000, 1, 2000, 3000]; 549 | /// assert_eq!(1, v.into_nonempty_iter().min()); 550 | /// ``` 551 | #[must_use] 552 | fn min(self) -> Self::Item 553 | where 554 | Self: Sized, 555 | Self::Item: Ord, 556 | { 557 | self.min_by(Ord::cmp) 558 | } 559 | 560 | /// Returns the element that gives the minimum value with respect to the 561 | /// given comparison function. 562 | /// 563 | /// Unlike [`Iterator::min_by`], this always yields a value. 564 | #[must_use] 565 | fn min_by(self, compare: F) -> Self::Item 566 | where 567 | Self: Sized, 568 | F: Fn(&Self::Item, &Self::Item) -> Ordering, 569 | { 570 | let (first, iter) = self.next(); 571 | 572 | iter.into_iter() 573 | .fold(first, |acc, item| match compare(&acc, &item) { 574 | Ordering::Greater => item, 575 | _ => acc, 576 | }) 577 | } 578 | 579 | /// Returns the element that gives the minimum value from the 580 | /// specified function. 581 | /// 582 | /// There are two differences with [`Iterator::min_by_key`]: 583 | /// - this function always yields a value while [`Iterator::min_by_key`] 584 | /// yields an `Option`. 585 | /// - if several elements are equally minimum, the *first* element is 586 | /// returned (unlike [`Iterator::min_by_key`] which returns the last 587 | /// element). 588 | /// 589 | /// # Examples 590 | /// 591 | /// ``` 592 | /// use nonempty_collections::*; 593 | /// let min = nev!["hi", "hello", "greetings", "hy"] 594 | /// .into_nonempty_iter() 595 | /// .min_by_key(|item| item.len()); 596 | /// assert_eq!("hi", min); 597 | /// ``` 598 | #[must_use] 599 | fn min_by_key(self, mut key: F) -> Self::Item 600 | where 601 | Self: Sized, 602 | B: Ord, 603 | F: FnMut(&Self::Item) -> B, 604 | { 605 | self.map(|item| (key(&item), item)) 606 | .min_by(|(left_key, _), (right_key, _)| left_key.cmp(right_key)) 607 | .1 608 | } 609 | 610 | /// Sort all iterator elements into a new non-empty iterator in ascending 611 | /// order. 612 | /// 613 | /// **Note:** This consumes the entire iterator, uses the 614 | /// [`NEVec::sort_by_key`] method and returns the result as a new iterator 615 | /// that owns its elements. 616 | /// 617 | /// This sort is stable (i.e., does not reorder equal elements). 618 | /// 619 | /// The sorted iterator, if directly collected to a `NEVec`, is converted 620 | /// without any extra copying or allocation cost. 621 | /// 622 | /// ``` 623 | /// use nonempty_collections::*; 624 | /// 625 | /// // sort people in descending order by age 626 | /// let people = nev![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 30)]; 627 | /// 628 | /// let oldest_people_first = people 629 | /// .into_nonempty_iter() 630 | /// .sorted_by_key(|x| -x.1) 631 | /// .map(|(person, _age)| person) 632 | /// .collect::>(); 633 | /// 634 | /// assert_eq!(nev!["Jill", "Jack", "Jane", "John"], oldest_people_first); 635 | /// ``` 636 | fn sorted_by_key(self, f: F) -> crate::vector::IntoIter 637 | where 638 | Self: Sized, 639 | K: Ord, 640 | F: FnMut(&Self::Item) -> K, 641 | { 642 | let mut v = NEVec::from_nonempty_iter(self); 643 | v.sort_by_key(f); 644 | v.into_nonempty_iter() 645 | } 646 | 647 | /// Returns the `n`th element of the iterator. 648 | /// 649 | /// This function consumes this `NonEmptyIterator`. [`Self::next()`] can be 650 | /// used for getting the first element and a reference to an iterator 651 | /// over the remaining elements. 652 | /// 653 | /// See also [`Iterator::nth`]. 654 | /// 655 | /// ``` 656 | /// use nonempty_collections::*; 657 | /// 658 | /// let n = nev![0, 1, 2, 3, 4, 5, 6]; 659 | /// assert_eq!(Some(&0), n.nonempty_iter().nth(0)); 660 | /// 661 | /// let n = nev![0, 1, 2, 3, 4, 5, 6]; 662 | /// assert_eq!(Some(&6), n.nonempty_iter().nth(6)); 663 | /// 664 | /// let n = nev![0, 1, 2, 3, 4, 5, 6]; 665 | /// assert_eq!(None, n.nonempty_iter().nth(100)); 666 | /// ``` 667 | fn nth(self, n: usize) -> Option 668 | where 669 | Self: Sized, 670 | { 671 | self.into_iter().nth(n) 672 | } 673 | 674 | /// Skip the first `n` elements. 675 | /// 676 | /// Note that the result will not be non-empty. 677 | /// 678 | /// See also [`Iterator::skip`]. 679 | /// 680 | /// ``` 681 | /// use nonempty_collections::*; 682 | /// 683 | /// let v = nev![1, 2, 3]; 684 | /// assert_eq!(Some(&3), v.nonempty_iter().skip(2).next()); 685 | /// ``` 686 | fn skip(self, n: usize) -> std::iter::Skip<::IntoIter> 687 | where 688 | Self: Sized, 689 | { 690 | self.into_iter().skip(n) 691 | } 692 | 693 | /// Skips over all initial elements that pass a given predicate. 694 | /// 695 | /// **Note**: This does not yield a non-empty iterator, since there is no 696 | /// guarantee that anything will fail the predicate. 697 | /// 698 | /// See also [`Iterator::skip_while`]. 699 | /// 700 | /// ``` 701 | /// use nonempty_collections::*; 702 | /// 703 | /// let v = nev![2, 4, 6, 7, 8]; 704 | /// let r: Vec<_> = v.into_nonempty_iter().skip_while(|n| n % 2 == 0).collect(); 705 | /// assert_eq!(vec![7, 8], r); 706 | /// ``` 707 | fn skip_while

(self, pred: P) -> std::iter::SkipWhile<::IntoIter, P> 708 | where 709 | Self: Sized, 710 | P: FnMut(&::Item) -> bool, 711 | { 712 | self.into_iter().skip_while(pred) 713 | } 714 | 715 | /// Sums the elements of a non-empty iterator. 716 | /// 717 | /// See also [`Iterator::sum`]. 718 | /// 719 | /// ``` 720 | /// use nonempty_collections::*; 721 | /// 722 | /// let sum: u32 = nev![1, 2, 3, 4].nonempty_iter().sum(); 723 | /// assert_eq!(10, sum); 724 | /// ``` 725 | #[must_use] 726 | fn sum(self) -> S 727 | where 728 | Self: Sized + IntoIterator, 729 | S: Sum<::Item>, 730 | { 731 | Sum::sum(self.into_iter()) 732 | } 733 | 734 | /// Iterates over the first `n` elements, or fewer if the underlying 735 | /// iterator ends sooner. 736 | /// 737 | /// See also [`Iterator::take`]. 738 | /// 739 | /// # Panics 740 | /// 741 | /// Panics if `n == 0`. 742 | /// 743 | /// # Examples 744 | /// 745 | /// ``` 746 | /// use core::num::NonZeroUsize; 747 | /// 748 | /// use nonempty_collections::*; 749 | /// 750 | /// let n: NEVec<_> = nev![1, 2, 3] 751 | /// .nonempty_iter() 752 | /// .map(|n| n * 2) 753 | /// .take(NonZeroUsize::new(2).unwrap()) 754 | /// .collect(); 755 | /// assert_eq!(nev![2, 4], n); 756 | /// ``` 757 | fn take(self, n: NonZeroUsize) -> Take 758 | where 759 | Self: Sized, 760 | { 761 | Take { 762 | iter: self.into_iter().take(n.get()), 763 | } 764 | } 765 | 766 | /// Iterates over all initial elements that pass a given predicate. 767 | /// 768 | /// **Note**: This does not yield a non-empty iterator, since there is no 769 | /// guarantee that anything will pass the predicate. 770 | /// 771 | /// See also [`Iterator::take_while`]. 772 | /// 773 | /// ``` 774 | /// use nonempty_collections::*; 775 | /// 776 | /// let v = nev![2, 4, 6, 7, 8]; 777 | /// let r: Vec<_> = v.into_nonempty_iter().take_while(|n| n % 2 == 0).collect(); 778 | /// assert_eq!(vec![2, 4, 6], r); 779 | /// ``` 780 | fn take_while

(self, pred: P) -> std::iter::TakeWhile<::IntoIter, P> 781 | where 782 | Self: Sized, 783 | P: FnMut(&::Item) -> bool, 784 | { 785 | self.into_iter().take_while(pred) 786 | } 787 | 788 | /// Iterates over the entire non-empty iterator, multiplying all the 789 | /// elements. 790 | /// 791 | /// See also [`Iterator::product`]. 792 | /// 793 | /// ``` 794 | /// use nonempty_collections::*; 795 | /// 796 | /// let prod: u32 = nev![1, 2, 3, 4].nonempty_iter().product(); 797 | /// assert_eq!(24, prod); 798 | /// ``` 799 | #[must_use] 800 | fn product

(self) -> P 801 | where 802 | Self: Sized + IntoIterator, 803 | P: Product<::Item>, 804 | { 805 | Product::product(self.into_iter()) 806 | } 807 | 808 | /// "Zips up" two non-empty iterators into a single one, while preserving 809 | /// non-emptiness. 810 | /// 811 | /// See also [`Iterator::zip`]. 812 | /// 813 | /// ``` 814 | /// use nonempty_collections::*; 815 | /// 816 | /// let a = nev![1, 2, 3]; 817 | /// let b = nev![4, 5, 6, 7]; 818 | /// let r = a 819 | /// .into_nonempty_iter() 820 | /// .zip(b) 821 | /// .map(|(av, bv)| av + bv) 822 | /// .collect(); 823 | /// assert_eq!(nev![5, 7, 9], r); 824 | /// ``` 825 | fn zip(self, other: U) -> Zip 826 | where 827 | Self: Sized, 828 | U: IntoNonEmptyIterator, 829 | { 830 | Zip { 831 | inner: self.into_iter().zip(other), 832 | } 833 | } 834 | 835 | /// Reduces the elements to a single one, by repeatedly applying a reducing 836 | /// operation. 837 | /// 838 | /// See also [`Iterator::reduce`]. 839 | /// 840 | /// ``` 841 | /// use nonempty_collections::*; 842 | /// 843 | /// let a = nev![1, 2, 3, 4]; 844 | /// let b = a.clone(); 845 | /// 846 | /// let x = a.into_nonempty_iter().reduce(|acc, v| acc + v); 847 | /// assert_eq!(x, 10); 848 | /// 849 | /// let y = b.into_nonempty_iter().reduce(|acc, v| acc * v); 850 | /// assert_eq!(y, 24); 851 | /// ``` 852 | #[must_use] 853 | fn reduce(self, f: F) -> Self::Item 854 | where 855 | Self: Sized, 856 | F: FnMut(Self::Item, Self::Item) -> Self::Item, 857 | { 858 | self.into_iter().reduce(f).unwrap() 859 | } 860 | } 861 | 862 | /// Conversion from a [`NonEmptyIterator`]. 863 | pub trait FromNonEmptyIterator: Sized { 864 | /// Creates a value from a [`NonEmptyIterator`]. 865 | fn from_nonempty_iter(iter: I) -> Self 866 | where 867 | I: IntoNonEmptyIterator; 868 | } 869 | 870 | impl FromNonEmptyIterator for Vec { 871 | fn from_nonempty_iter(iter: I) -> Self 872 | where 873 | I: IntoNonEmptyIterator, 874 | { 875 | iter.into_nonempty_iter().into_iter().collect() 876 | } 877 | } 878 | 879 | impl FromNonEmptyIterator<(K, V)> for HashMap 880 | where 881 | K: Eq + Hash, 882 | S: BuildHasher + Default, 883 | { 884 | fn from_nonempty_iter(iter: I) -> Self 885 | where 886 | I: IntoNonEmptyIterator, 887 | { 888 | iter.into_nonempty_iter().into_iter().collect() 889 | } 890 | } 891 | 892 | impl FromNonEmptyIterator for HashSet 893 | where 894 | T: Eq + Hash, 895 | S: BuildHasher + Default, 896 | { 897 | fn from_nonempty_iter(iter: I) -> Self 898 | where 899 | I: IntoNonEmptyIterator, 900 | { 901 | iter.into_nonempty_iter().into_iter().collect() 902 | } 903 | } 904 | 905 | impl FromNonEmptyIterator> for Result 906 | where 907 | V: FromNonEmptyIterator, 908 | { 909 | fn from_nonempty_iter(iter: I) -> Result 910 | where 911 | I: IntoNonEmptyIterator>, 912 | { 913 | let (head, rest) = iter.into_nonempty_iter().next(); 914 | let head: A = head?; 915 | 916 | let mut buf = NEVec::new(head); 917 | 918 | for item in rest { 919 | let item: A = item?; 920 | buf.push(item); 921 | } 922 | let new_iter = buf.into_nonempty_iter(); 923 | let output: V = FromNonEmptyIterator::from_nonempty_iter(new_iter); 924 | Ok(output) 925 | } 926 | } 927 | 928 | /// Conversion into a [`NonEmptyIterator`]. 929 | pub trait IntoNonEmptyIterator: IntoIterator { 930 | /// Which kind of [`NonEmptyIterator`] are we turning this into? 931 | type IntoNEIter: NonEmptyIterator; 932 | 933 | /// Creates a [`NonEmptyIterator`] from a value. 934 | fn into_nonempty_iter(self) -> Self::IntoNEIter; 935 | } 936 | 937 | impl IntoNonEmptyIterator for I { 938 | type IntoNEIter = I; 939 | 940 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 941 | self 942 | } 943 | } 944 | 945 | /// Similar to [`std::iter::Map`], but with additional non-emptiness guarantees. 946 | #[derive(Clone)] 947 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 948 | pub struct Map { 949 | iter: std::iter::Map, 950 | } 951 | 952 | impl NonEmptyIterator for Map 953 | where 954 | I: NonEmptyIterator, 955 | F: FnMut(I::Item) -> U, 956 | { 957 | } 958 | 959 | /// ``` 960 | /// use nonempty_collections::*; 961 | /// 962 | /// let v: Vec<_> = nev![1, 2, 3].nonempty_iter().map(|n| n * 2).collect(); 963 | /// ``` 964 | impl IntoIterator for Map 965 | where 966 | I: NonEmptyIterator, 967 | F: FnMut(I::Item) -> U, 968 | { 969 | type Item = U; 970 | 971 | type IntoIter = std::iter::Map; 972 | 973 | fn into_iter(self) -> Self::IntoIter { 974 | self.iter 975 | } 976 | } 977 | 978 | impl std::fmt::Debug for Map 979 | where 980 | I: NonEmptyIterator, 981 | I::IntoIter: std::fmt::Debug, 982 | { 983 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 984 | self.iter.fmt(f) 985 | } 986 | } 987 | 988 | /// An iterator that clones the elements of an underlying iterator. 989 | /// 990 | /// See also [`std::iter::Cloned`]. 991 | #[derive(Clone)] 992 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 993 | pub struct Cloned { 994 | iter: I, 995 | } 996 | 997 | impl<'a, I, T: 'a> NonEmptyIterator for Cloned 998 | where 999 | I: NonEmptyIterator, 1000 | T: Clone, 1001 | { 1002 | } 1003 | 1004 | impl<'a, I, T: 'a> IntoIterator for Cloned 1005 | where 1006 | I: IntoIterator, 1007 | T: Clone, 1008 | { 1009 | type Item = T; 1010 | 1011 | type IntoIter = std::iter::Cloned; 1012 | 1013 | fn into_iter(self) -> Self::IntoIter { 1014 | self.iter.into_iter().cloned() 1015 | } 1016 | } 1017 | 1018 | impl std::fmt::Debug for Cloned { 1019 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1020 | self.iter.fmt(f) 1021 | } 1022 | } 1023 | 1024 | /// An iterator that yields the current count and the element during iteration. 1025 | /// 1026 | /// See also [`std::iter::Enumerate`]. 1027 | #[derive(Clone)] 1028 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1029 | pub struct Enumerate { 1030 | iter: I, 1031 | } 1032 | 1033 | impl NonEmptyIterator for Enumerate where I: NonEmptyIterator {} 1034 | 1035 | impl IntoIterator for Enumerate 1036 | where 1037 | I: IntoIterator, 1038 | { 1039 | type Item = (usize, I::Item); 1040 | 1041 | type IntoIter = std::iter::Enumerate; 1042 | 1043 | fn into_iter(self) -> Self::IntoIter { 1044 | self.iter.into_iter().enumerate() 1045 | } 1046 | } 1047 | 1048 | impl std::fmt::Debug for Enumerate { 1049 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1050 | self.iter.fmt(f) 1051 | } 1052 | } 1053 | 1054 | /// A non-empty iterator that only iterates over the first `n` iterations. 1055 | /// 1056 | /// See also [`Iterator::take`]. 1057 | #[derive(Clone)] 1058 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1059 | pub struct Take { 1060 | iter: std::iter::Take, 1061 | } 1062 | 1063 | impl NonEmptyIterator for Take where I: NonEmptyIterator {} 1064 | 1065 | /// ``` 1066 | /// use core::num::NonZeroUsize; 1067 | /// 1068 | /// use nonempty_collections::*; 1069 | /// 1070 | /// let v = nev![1, 2, 3]; 1071 | /// let r = v 1072 | /// .nonempty_iter() 1073 | /// .take(NonZeroUsize::new(1).unwrap()) 1074 | /// .into_iter() 1075 | /// .count(); 1076 | /// assert_eq!(1, r); 1077 | /// ``` 1078 | impl IntoIterator for Take 1079 | where 1080 | I: NonEmptyIterator, 1081 | { 1082 | type Item = I::Item; 1083 | 1084 | type IntoIter = std::iter::Take; 1085 | 1086 | fn into_iter(self) -> Self::IntoIter { 1087 | self.iter 1088 | } 1089 | } 1090 | 1091 | impl std::fmt::Debug for Take 1092 | where 1093 | I: NonEmptyIterator, 1094 | I::IntoIter: std::fmt::Debug, 1095 | { 1096 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1097 | self.iter.fmt(f) 1098 | } 1099 | } 1100 | 1101 | /// A non-empty iterator that links two iterators together, in a chain. 1102 | #[derive(Clone)] 1103 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1104 | pub struct Chain { 1105 | inner: std::iter::Chain, 1106 | } 1107 | 1108 | impl NonEmptyIterator for Chain 1109 | where 1110 | A: Iterator, 1111 | B: Iterator, 1112 | { 1113 | } 1114 | 1115 | impl IntoIterator for Chain 1116 | where 1117 | A: Iterator, 1118 | B: Iterator, 1119 | { 1120 | type Item = A::Item; 1121 | 1122 | type IntoIter = std::iter::Chain; 1123 | 1124 | fn into_iter(self) -> Self::IntoIter { 1125 | self.inner 1126 | } 1127 | } 1128 | 1129 | impl std::fmt::Debug for Chain 1130 | where 1131 | A: std::fmt::Debug, 1132 | B: std::fmt::Debug, 1133 | { 1134 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1135 | self.inner.fmt(f) 1136 | } 1137 | } 1138 | 1139 | /// A non-empty iterator that yields an element exactly once. 1140 | #[derive(Clone)] 1141 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1142 | pub struct Once { 1143 | inner: std::iter::Once, 1144 | } 1145 | 1146 | impl Once { 1147 | pub(crate) fn new(value: T) -> Once { 1148 | Once { 1149 | inner: std::iter::once(value), 1150 | } 1151 | } 1152 | } 1153 | 1154 | impl NonEmptyIterator for Once {} 1155 | 1156 | impl IntoIterator for Once { 1157 | type Item = T; 1158 | 1159 | type IntoIter = std::iter::Once; 1160 | 1161 | fn into_iter(self) -> Self::IntoIter { 1162 | self.inner 1163 | } 1164 | } 1165 | 1166 | impl std::fmt::Debug for Once { 1167 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1168 | self.inner.fmt(f) 1169 | } 1170 | } 1171 | 1172 | /// A non-empty iterator that copies the elements of an underlying non-empty 1173 | /// iterator. 1174 | /// 1175 | /// See also [`std::iter::Copied`]. 1176 | #[derive(Clone)] 1177 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1178 | pub struct Copied { 1179 | iter: std::iter::Copied, 1180 | } 1181 | 1182 | impl<'a, I, T: 'a> NonEmptyIterator for Copied 1183 | where 1184 | I: Iterator, 1185 | T: Copy, 1186 | { 1187 | } 1188 | 1189 | impl<'a, I, T: 'a> IntoIterator for Copied 1190 | where 1191 | I: Iterator, 1192 | T: Copy, 1193 | { 1194 | type Item = T; 1195 | 1196 | type IntoIter = std::iter::Copied; 1197 | 1198 | fn into_iter(self) -> Self::IntoIter { 1199 | self.iter 1200 | } 1201 | } 1202 | 1203 | impl<'a, I, T: 'a> std::fmt::Debug for Copied 1204 | where 1205 | I: Iterator + std::fmt::Debug, 1206 | { 1207 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1208 | self.iter.fmt(f) 1209 | } 1210 | } 1211 | 1212 | /// A non-empty iterator that "zips up" its sources. 1213 | /// 1214 | /// See also [`std::iter::Zip`]. 1215 | #[derive(Clone)] 1216 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1217 | pub struct Zip { 1218 | inner: std::iter::Zip, 1219 | } 1220 | 1221 | impl NonEmptyIterator for Zip 1222 | where 1223 | A: Iterator, 1224 | B: Iterator, 1225 | { 1226 | } 1227 | 1228 | impl IntoIterator for Zip 1229 | where 1230 | A: Iterator, 1231 | B: Iterator, 1232 | { 1233 | type Item = (A::Item, B::Item); 1234 | 1235 | type IntoIter = std::iter::Zip; 1236 | 1237 | fn into_iter(self) -> Self::IntoIter { 1238 | self.inner 1239 | } 1240 | } 1241 | 1242 | impl std::fmt::Debug for Zip 1243 | where 1244 | A: std::fmt::Debug, 1245 | B: std::fmt::Debug, 1246 | { 1247 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1248 | self.inner.fmt(f) 1249 | } 1250 | } 1251 | 1252 | /// Wrapper struct for powering [`NonEmptyIterator::group_by`]. 1253 | #[derive(Debug)] 1254 | pub struct NEGroupBy { 1255 | iter: I, 1256 | f: F, 1257 | } 1258 | 1259 | impl NonEmptyIterator for NEGroupBy 1260 | where 1261 | I: NonEmptyIterator, 1262 | F: FnMut(&I::Item) -> K, 1263 | K: PartialEq, 1264 | { 1265 | } 1266 | 1267 | impl IntoIterator for NEGroupBy 1268 | where 1269 | I: IntoIterator, 1270 | F: FnMut(&I::Item) -> K, 1271 | K: PartialEq, 1272 | { 1273 | type Item = NEVec; 1274 | 1275 | type IntoIter = GroupBy<::IntoIter, K, I::Item, F>; 1276 | 1277 | fn into_iter(self) -> Self::IntoIter { 1278 | GroupBy { 1279 | iter: self.iter.into_iter(), 1280 | f: Rc::new(RefCell::new(self.f)), 1281 | prev: None, 1282 | curr: None, 1283 | } 1284 | } 1285 | } 1286 | 1287 | /// A (possibly empty) definition of the group-by operation that enables 1288 | /// [`NEGroupBy`] to be written. You aren't expected to use this directly, thus 1289 | /// there is no way to construct one. 1290 | #[derive(Debug)] 1291 | pub struct GroupBy { 1292 | iter: I, 1293 | f: Rc>, 1294 | prev: Option, 1295 | curr: Option>, 1296 | } 1297 | 1298 | impl Iterator for GroupBy 1299 | where 1300 | I: Iterator, 1301 | F: FnMut(&I::Item) -> K, 1302 | K: PartialEq, 1303 | { 1304 | type Item = NEVec; 1305 | 1306 | fn next(&mut self) -> Option { 1307 | loop { 1308 | match self.iter.next() { 1309 | None => return self.curr.take(), 1310 | Some(v) => { 1311 | let k = { 1312 | let mut f = self.f.borrow_mut(); 1313 | f(&v) 1314 | }; 1315 | 1316 | match (self.prev.as_ref(), &mut self.curr) { 1317 | // Continue some run of similar values. 1318 | (Some(p), Some(c)) if p == &k => { 1319 | c.push(v); 1320 | } 1321 | // We found a break; finally yield an NEVec. 1322 | (Some(_), Some(_)) => { 1323 | let curr = self.curr.take(); 1324 | self.curr = Some(nev![v]); 1325 | self.prev = Some(k); 1326 | return curr; 1327 | } 1328 | // Very first iteration. 1329 | (_, _) => { 1330 | self.prev = Some(k); 1331 | self.curr = Some(nev![v]); 1332 | } 1333 | } 1334 | } 1335 | } 1336 | } 1337 | } 1338 | } 1339 | 1340 | /// Flatten nested, non-empty structures. 1341 | /// 1342 | /// See also [`std::iter::FlatMap`]. 1343 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1344 | pub struct FlatMap { 1345 | inner: std::iter::FlatMap, 1346 | } 1347 | 1348 | impl U> NonEmptyIterator for FlatMap {} 1349 | 1350 | /// ``` 1351 | /// use nonempty_collections::*; 1352 | /// 1353 | /// let v = nev![1, 2, 3]; 1354 | /// let r: Vec<_> = v 1355 | /// .into_nonempty_iter() 1356 | /// .flat_map(|n| nev![n]) 1357 | /// .into_iter() 1358 | /// .collect(); 1359 | /// assert_eq!(vec![1, 2, 3], r); 1360 | /// ``` 1361 | impl U> IntoIterator for FlatMap { 1362 | type Item = U::Item; 1363 | 1364 | type IntoIter = std::iter::FlatMap; 1365 | 1366 | fn into_iter(self) -> Self::IntoIter { 1367 | self.inner 1368 | } 1369 | } 1370 | 1371 | impl std::fmt::Debug for FlatMap 1372 | where 1373 | U: IntoIterator, 1374 | U::IntoIter: std::fmt::Debug, 1375 | { 1376 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1377 | self.inner.fmt(f) 1378 | } 1379 | } 1380 | 1381 | impl Clone for FlatMap 1382 | where 1383 | U: Clone + IntoIterator, 1384 | U::IntoIter: Clone, 1385 | { 1386 | fn clone(&self) -> Self { 1387 | FlatMap { 1388 | inner: self.inner.clone(), 1389 | } 1390 | } 1391 | } 1392 | 1393 | /// An adapter for regular iterators that are known to be non-empty. 1394 | #[derive(Clone)] 1395 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1396 | pub struct NonEmptyIterAdapter { 1397 | inner: I, 1398 | } 1399 | 1400 | impl NonEmptyIterator for NonEmptyIterAdapter {} 1401 | 1402 | impl IntoIterator for NonEmptyIterAdapter 1403 | where 1404 | I: Iterator, 1405 | { 1406 | type Item = I::Item; 1407 | 1408 | type IntoIter = I; 1409 | 1410 | fn into_iter(self) -> Self::IntoIter { 1411 | self.inner 1412 | } 1413 | } 1414 | 1415 | impl std::fmt::Debug for NonEmptyIterAdapter { 1416 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1417 | self.inner.fmt(f) 1418 | } 1419 | } 1420 | 1421 | /// Convenience trait extending [`IntoIterator`]. 1422 | pub trait IntoIteratorExt { 1423 | /// The type of the elements being iterated over. 1424 | type Item; 1425 | /// Which kind of [`NonEmptyIterator`] are we turning this into? 1426 | type IntoIter: NonEmptyIterator; 1427 | 1428 | /// Tries to convert `self` into a [`NonEmptyIterator`]. 1429 | /// 1430 | /// ``` 1431 | /// use nonempty_collections::*; 1432 | /// 1433 | /// let a = vec![1]; 1434 | /// let x = a.try_into_nonempty_iter(); 1435 | /// assert!(x.is_some()); 1436 | /// 1437 | /// let y = x.unwrap().collect::>(); 1438 | /// assert_eq!(y.len().get(), 1); 1439 | /// ``` 1440 | /// 1441 | /// ``` 1442 | /// use nonempty_collections::*; 1443 | /// 1444 | /// let b: Vec = vec![]; 1445 | /// let x = b.try_into_nonempty_iter(); 1446 | /// 1447 | /// assert!(x.is_none()); 1448 | /// ``` 1449 | /// 1450 | /// To construct non-empty collections directly, consider macros like 1451 | /// [`crate::nev!`]. 1452 | fn try_into_nonempty_iter(self) -> Option; 1453 | } 1454 | 1455 | impl IntoIteratorExt for T 1456 | where 1457 | T: IntoIterator, 1458 | { 1459 | type Item = T::Item; 1460 | 1461 | type IntoIter = NonEmptyIterAdapter>; 1462 | 1463 | /// Converts `self` into a non-empty iterator or returns `None` if 1464 | /// the iterator is empty. 1465 | fn try_into_nonempty_iter(self) -> Option { 1466 | let mut iter = self.into_iter().peekable(); 1467 | iter.peek() 1468 | .is_some() 1469 | .then_some(NonEmptyIterAdapter { inner: iter }) 1470 | } 1471 | } 1472 | 1473 | /// A non-empty iterator with a `peek()` that returns a reference to the first 1474 | /// element. 1475 | /// 1476 | /// This `struct` is created by the [`peekable`] method on [`NonEmptyIterator`]. 1477 | /// See its documentation for more. 1478 | /// 1479 | /// [`peekable`]: NonEmptyIterator::peekable 1480 | #[derive(Debug, Clone)] 1481 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1482 | pub struct Peekable { 1483 | first: I::Item, 1484 | rest: I, 1485 | } 1486 | 1487 | impl Peekable { 1488 | /// Returns a reference to the first value without advancing or consuming 1489 | /// the iterator. 1490 | pub const fn peek(&self) -> &I::Item { 1491 | &self.first 1492 | } 1493 | 1494 | /// Returns a mutable reference to the first value without advancing or 1495 | /// consuming the iterator. 1496 | pub fn peek_mut(&mut self) -> &mut I::Item { 1497 | &mut self.first 1498 | } 1499 | } 1500 | 1501 | impl NonEmptyIterator for Peekable {} 1502 | 1503 | impl IntoIterator for Peekable { 1504 | type Item = I::Item; 1505 | 1506 | type IntoIter = std::iter::Chain, I>; 1507 | 1508 | fn into_iter(self) -> Self::IntoIter { 1509 | std::iter::once(self.first).chain(self.rest) 1510 | } 1511 | } 1512 | 1513 | #[cfg(test)] 1514 | mod tests { 1515 | use super::*; 1516 | use crate::nem; 1517 | use crate::NEMap; 1518 | 1519 | #[test] 1520 | fn into_hashset() { 1521 | let m = nem!['a' => 1, 'b' => 2, 'c' => 3]; 1522 | let _: HashSet<_> = m.values().collect(); 1523 | } 1524 | 1525 | #[test] 1526 | fn into_hashmap() { 1527 | let m = nem!['a' => 1, 'b' => 2, 'c' => 3]; 1528 | let h: HashMap<_, _> = m.iter().map(|(k, v)| (*k, *v)).collect(); 1529 | let n = NEMap::try_from(h).unwrap(); 1530 | assert_eq!(m, n); 1531 | } 1532 | 1533 | #[test] 1534 | fn peekable() { 1535 | let v = nev![0, 1, 2, 3]; 1536 | 1537 | let iter = v.into_nonempty_iter().peekable(); 1538 | assert_eq!(&0, iter.peek()); 1539 | 1540 | let all = iter.collect::>(); 1541 | assert_eq!(nev![0, 1, 2, 3], all); 1542 | 1543 | let mut iter = all.into_nonempty_iter().peekable(); 1544 | 1545 | *iter.peek_mut() = 7; 1546 | 1547 | let (first, rest) = iter.next(); 1548 | assert_eq!(7, first); 1549 | assert_eq!(vec![1, 2, 3], rest.collect::>()); 1550 | 1551 | let u = nev![0, 1, 2]; 1552 | let p: NEVec<_> = u 1553 | .into_nonempty_iter() 1554 | .map(|n| n + 1) 1555 | .peekable() 1556 | .map(|n| n * 2) 1557 | .collect(); 1558 | assert_eq!(nev![2, 4, 6], p); 1559 | } 1560 | } 1561 | -------------------------------------------------------------------------------- /src/itertools.rs: -------------------------------------------------------------------------------- 1 | //! Extra non-empty iterator adaptors, functions and macros. 2 | //! 3 | //! To extend [`NonEmptyIterator`] with methods in this crate, import 4 | //! the [`NonEmptyItertools`] trait: 5 | //! 6 | //! ``` 7 | //! use nonempty_collections::NonEmptyItertools; 8 | //! ``` 9 | 10 | use core::fmt; 11 | use std::fmt::Debug; 12 | 13 | use itertools::Itertools; 14 | 15 | use crate::IntoNonEmptyIterator; 16 | use crate::NonEmptyIterator; 17 | 18 | /// A [`NonEmptyIterator`] blanket implementation that provides extra adaptors 19 | /// and methods, similar to [`Itertools`](https://docs.rs/itertools/) for `Iterator`. 20 | pub trait NonEmptyItertools: NonEmptyIterator { 21 | /// Return a non-empty iterator adaptor that iterates over the non-empty 22 | /// cartesian product of the element sets of two iterators `self` and 23 | /// `J`. 24 | /// 25 | /// `NonEmptyIterator`element type is `(Self::Item, J::Item)`. 26 | /// 27 | /// ``` 28 | /// use nonempty_collections::*; 29 | /// 30 | /// let product = nev![0, 1] 31 | /// .nonempty_iter() 32 | /// .copied() 33 | /// .cartesian_product("αβ".chars().try_into_nonempty_iter().unwrap()) 34 | /// .collect::>(); 35 | /// assert_eq!(nev![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')], product); 36 | /// ``` 37 | fn cartesian_product(self, other: J) -> Product 38 | where 39 | Self: Sized, 40 | Self::Item: Clone, 41 | J: IntoNonEmptyIterator, 42 | ::IntoIter: Clone, 43 | { 44 | Product { 45 | inner: Itertools::cartesian_product(self.into_iter(), other.into_nonempty_iter()), 46 | } 47 | } 48 | 49 | /// Check whether all elements are unique (non equal). 50 | /// 51 | /// # Examples 52 | /// 53 | /// ``` 54 | /// use nonempty_collections::*; 55 | /// 56 | /// let data = nev![1, 2, 3, 4, 1, 5]; 57 | /// assert!(!nev![1, 2, 3, 4, 1, 5].nonempty_iter().all_unique()); 58 | /// assert!(nev![2, 3, 4, 1, 5].nonempty_iter().all_unique()); 59 | /// ``` 60 | #[must_use] 61 | fn all_unique(self) -> bool 62 | where 63 | Self: Sized, 64 | Self::Item: Eq + std::hash::Hash, 65 | { 66 | self.into_iter().all_unique() 67 | } 68 | } 69 | 70 | impl NonEmptyItertools for T where T: NonEmptyIterator + ?Sized {} 71 | 72 | /// A non-empty iterator adaptor that iterates over the cartesian product of 73 | /// the element sets of two iterators `I` and `J`. 74 | /// 75 | /// Iterator element type is `(I::Item, J::Item)`. 76 | /// 77 | /// See [`.cartesian_product()`](crate::itertools::Itertools::cartesian_product) 78 | /// for more information. 79 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 80 | pub struct Product 81 | where 82 | I: NonEmptyIterator, 83 | J: NonEmptyIterator, 84 | { 85 | inner: itertools::Product, 86 | } 87 | 88 | impl NonEmptyIterator for Product 89 | where 90 | I: NonEmptyIterator, 91 | J: NonEmptyIterator, 92 | J::Item: Clone, 93 | I::Item: Clone, 94 | J::IntoIter: Clone, 95 | I::IntoIter: Clone, 96 | { 97 | } 98 | 99 | impl IntoIterator for Product 100 | where 101 | I: NonEmptyIterator, 102 | J: NonEmptyIterator, 103 | J::Item: Clone, 104 | I::Item: Clone, 105 | J::IntoIter: Clone, 106 | I::IntoIter: Clone, 107 | { 108 | type Item = (I::Item, J::Item); 109 | 110 | type IntoIter = itertools::Product; 111 | 112 | fn into_iter(self) -> Self::IntoIter { 113 | self.inner 114 | } 115 | } 116 | 117 | impl Debug for Product 118 | where 119 | I: NonEmptyIterator, 120 | J: NonEmptyIterator, 121 | I::Item: Debug, 122 | J::Item: Debug, 123 | I::IntoIter: Debug, 124 | J::IntoIter: Debug, 125 | { 126 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 127 | Debug::fmt(&self.inner, f) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(rustdoc::redundant_explicit_links)] // the explicit links are needed for cargo rdme 2 | 3 | //! Non-empty variants of the standard collections. 4 | //! 5 | //! Non-emptiness can be a powerful guarantee. If your main use of `Vec` is as 6 | //! an `Iterator`, then you may not need to distinguish on emptiness. But there 7 | //! are indeed times when the `Vec` you receive as a function argument needs to 8 | //! be non-empty or your function can't proceed. Similarly, there are times when 9 | //! the `Vec` you return to a calling user needs to promise it actually contains 10 | //! something. 11 | //! 12 | //! With `NEVec`, you're freed from the boilerplate of constantly needing to 13 | //! check `is_empty()` or pattern matching before proceeding, or erroring if you 14 | //! can't. So overall, code, type signatures, and logic become cleaner. 15 | //! 16 | //! Consider that unlike `Vec`, [`NEVec::first()`] and [`NEVec::last()`] don't 17 | //! return in `Option`; they always succeed. 18 | //! 19 | //! Alongside [`NEVec`](crate::vector::NEVec) are its cousins 20 | //! [`NESlice`](crate::slice::NESlice), [`NEMap`](crate::map::NEMap), and 21 | //! [`NESet`](crate::set::NESet), which are all guaranteed to contain at least 22 | //! one item. 23 | //! 24 | //! # Examples 25 | //! 26 | //! The simplest way to construct these non-empty collections is via their 27 | //! macros: [`nev!`], [`nes!`], and [`nem!`]: 28 | //! 29 | //! ``` 30 | //! use nonempty_collections::*; 31 | //! 32 | //! let v: NEVec = nev![1, 2, 3]; 33 | //! let s: NESet = nes![1, 2, 2, 3]; // 1 2 3 34 | //! let m: NEMap<&str, bool> = nem!["a" => true, "b" => false]; 35 | //! assert_eq!(&1, v.first()); 36 | //! assert_eq!(3, s.len().get()); 37 | //! assert!(m.get("a").unwrap()); 38 | //! ``` 39 | //! 40 | //! Unlike the familiar `vec!` macro, `nev!` and friends require at least one 41 | //! element: 42 | //! 43 | //! ``` 44 | //! use nonempty_collections::nev; 45 | //! 46 | //! let v = nev![1]; 47 | //! ``` 48 | //! 49 | //! A value must be provided: 50 | //! 51 | //! ```compile_fail 52 | //! let v = nev![]; // Doesn't compile! 53 | //! ``` 54 | //! 55 | //! Like `Vec`, you can also construct a [`NEVec`](crate::vector::NEVec) the old 56 | //! fashioned way with [`NEVec::new()`] or its constructor: 57 | //! 58 | //! ``` 59 | //! use nonempty_collections::NEVec; 60 | //! 61 | //! let mut l = NEVec::try_from_vec(vec![42, 36, 58]).unwrap(); 62 | //! assert_eq!(&42, l.first()); 63 | //! 64 | //! l.push(9001); 65 | //! assert_eq!(l.last(), &9001); 66 | //! ``` 67 | //! 68 | //! And if necessary, you're free to convert to and from `Vec`: 69 | //! 70 | //! ``` 71 | //! use nonempty_collections::nev; 72 | //! use nonempty_collections::NEVec; 73 | //! 74 | //! let l: NEVec = nev![42, 36, 58, 9001]; 75 | //! let v: Vec = l.into(); 76 | //! assert_eq!(v, vec![42, 36, 58, 9001]); 77 | //! 78 | //! let u: Option> = NEVec::try_from_vec(v); 79 | //! assert_eq!(Some(nev![42, 36, 58, 9001]), u); 80 | //! ``` 81 | //! 82 | //! # Iterators 83 | //! 84 | //! This library extends the notion of non-emptiness to iterators, and provides 85 | //! the [`NonEmptyIterator`](crate::iter::NonEmptyIterator) trait. This has some 86 | //! interesting consequences: 87 | //! 88 | //! - Functions like `map` preserve non-emptiness. 89 | //! - Functions like `max` always have a result. 90 | //! - A non-empty iterator chain can be `collect`ed back into a non-empty 91 | //! structure. 92 | //! - You can chain many operations together without having to double-check for 93 | //! emptiness. 94 | //! 95 | //! ``` 96 | //! use nonempty_collections::*; 97 | //! 98 | //! let v: NEVec<_> = nev![1, 2, 3].into_nonempty_iter().map(|n| n + 1).collect(); 99 | //! assert_eq!(&2, v.first()); 100 | //! ``` 101 | //! 102 | //! Consider also [`IntoIteratorExt::try_into_nonempty_iter`] for converting any 103 | //! given [`Iterator`] and [`IntoIterator`] into a non-empty one, if it contains 104 | //! at least one item. 105 | //! 106 | //! # Arrays 107 | //! 108 | //! Since fixed-size arrays are by definition already not empty, they aren't 109 | //! given a special wrapper type like [`NEVec`](crate::vector::NEVec). Instead, 110 | //! we enable them to be easily iterated over in a compatible way: 111 | //! 112 | //! ``` 113 | //! use nonempty_collections::*; 114 | //! 115 | //! let a: [u32; 4] = [1, 2, 3, 4]; 116 | //! let v: NEVec<_> = a.into_nonempty_iter().map(|n| n + 1).collect(); 117 | //! assert_eq!(nev![2, 3, 4, 5], v); 118 | //! ``` 119 | //! See [`NonEmptyArrayExt`](crate::array::NonEmptyArrayExt) for more 120 | //! conversions. 121 | //! 122 | //! # Caveats 123 | //! 124 | //! Since `NEVec`, `NEMap`, and `NESet` must have a least one element, it is not 125 | //! possible to implement the [`FromIterator`] trait for them. We can't 126 | //! know, in general, if any given standard-library [`Iterator`] actually 127 | //! contains something. 128 | //! 129 | //! # Features 130 | //! 131 | //! * `serde`: `serde` support. 132 | //! * `indexmap`: adds [`NEIndexMap`](crate::index_map::NEIndexMap) a non-empty [`IndexMap`](https://docs.rs/indexmap/latest/indexmap/). 133 | //! * `itertools`: adds [`NonEmptyItertools`](crate::itertools::NonEmptyItertools) a non-empty variant of [`itertools`](https://docs.rs/itertools/latest/itertools/). 134 | //! * `either`: adds [`NEEither`](crate::either::NEEither) a non-empty variant of `Either` from the [`either` crate](https://docs.rs/either/latest/either/). 135 | 136 | pub mod array; 137 | pub mod iter; 138 | pub mod map; 139 | pub mod set; 140 | pub mod slice; 141 | pub mod vector; 142 | 143 | #[cfg(feature = "either")] 144 | pub mod either; 145 | #[cfg(feature = "indexmap")] 146 | pub mod index_map; 147 | #[cfg(feature = "itertools")] 148 | pub mod itertools; 149 | 150 | pub use array::ArrayNonEmptyIterator; 151 | pub use array::NonEmptyArrayExt; 152 | #[cfg(feature = "either")] 153 | pub use either::NEEither; 154 | #[cfg(feature = "indexmap")] 155 | pub use index_map::NEIndexMap; 156 | pub use iter::FromNonEmptyIterator; 157 | pub use iter::IntoIteratorExt; 158 | pub use iter::IntoNonEmptyIterator; 159 | pub use iter::NonEmptyIterator; 160 | #[cfg(feature = "itertools")] 161 | pub use itertools::NonEmptyItertools; 162 | pub use map::NEMap; 163 | pub use set::NESet; 164 | pub use slice::NESlice; 165 | pub use vector::NEVec; 166 | 167 | /// Errors typically involving type conversions. 168 | #[derive(Debug, Clone, Copy)] 169 | pub enum Error { 170 | /// There was nothing to decode. 171 | Empty, 172 | } 173 | 174 | impl std::fmt::Display for Error { 175 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 176 | match self { 177 | Error::Empty => write!(f, "Given collection was empty"), 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/map.rs: -------------------------------------------------------------------------------- 1 | //! Non-empty [`HashMap`]s. 2 | 3 | use core::fmt; 4 | use std::borrow::Borrow; 5 | use std::collections::HashMap; 6 | use std::hash::BuildHasher; 7 | use std::hash::Hash; 8 | use std::num::NonZeroUsize; 9 | 10 | #[cfg(feature = "serde")] 11 | use serde::Deserialize; 12 | #[cfg(feature = "serde")] 13 | use serde::Serialize; 14 | 15 | use crate::FromNonEmptyIterator; 16 | use crate::IntoIteratorExt; 17 | use crate::IntoNonEmptyIterator; 18 | use crate::NonEmptyIterator; 19 | 20 | /// Like the [`crate::nev!`] macro, but for Maps. A nice short-hand for 21 | /// constructing [`NEMap`] values. 22 | /// 23 | /// ``` 24 | /// use nonempty_collections::nem; 25 | /// 26 | /// let m = nem! {"elves" => 3000, "orcs" => 10000}; 27 | /// assert_eq!(2, m.len().get()); 28 | /// ``` 29 | #[macro_export] 30 | macro_rules! nem { 31 | ($hk:expr => $hv:expr, $( $xk:expr => $xv:expr ),* $(,)?) => {{ 32 | let mut map = $crate::NEMap::new($hk, $hv); 33 | $( map.insert($xk, $xv); )* 34 | map 35 | }}; 36 | ($hk:expr => $hv:expr) => { 37 | $crate::NEMap::new($hk, $hv) 38 | } 39 | } 40 | 41 | /// A non-empty, growable `HashMap`. 42 | /// 43 | /// ``` 44 | /// use nonempty_collections::nem; 45 | /// 46 | /// let m = nem!["elves" => 3000, "orcs" => 10000]; 47 | /// assert_eq!(2, m.len().get()); 48 | /// ``` 49 | #[allow(clippy::unsafe_derive_deserialize)] 50 | #[cfg_attr( 51 | feature = "serde", 52 | derive(Deserialize, Serialize), 53 | serde(bound( 54 | serialize = "K: Eq + Hash + Clone + Serialize, V: Clone + Serialize, S: Clone + BuildHasher", 55 | deserialize = "K: Eq + Hash + Clone + Deserialize<'de>, V: Deserialize<'de>, S: Default + BuildHasher" 56 | )), 57 | serde(into = "HashMap", try_from = "HashMap") 58 | )] 59 | #[derive(Clone)] 60 | pub struct NEMap { 61 | inner: HashMap, 62 | } 63 | 64 | impl NEMap 65 | where 66 | K: Eq + Hash, 67 | { 68 | /// Creates a new `NEMap` with a single element. 69 | #[must_use] 70 | pub fn new(k: K, v: V) -> NEMap { 71 | let mut inner = HashMap::new(); 72 | inner.insert(k, v); 73 | NEMap { inner } 74 | } 75 | 76 | /// Creates a new `NEMap` with a single element and specified capacity. 77 | /// ``` 78 | /// use std::num::*; 79 | /// 80 | /// use nonempty_collections::*; 81 | /// let map = NEMap::with_capacity(NonZeroUsize::MIN, 1, 1); 82 | /// assert_eq!(nem! { 1 => 1 }, map); 83 | /// assert!(map.capacity().get() >= 1); 84 | /// ``` 85 | #[must_use] 86 | pub fn with_capacity(capacity: NonZeroUsize, k: K, v: V) -> NEMap { 87 | let mut inner = HashMap::with_capacity(capacity.get()); 88 | inner.insert(k, v); 89 | NEMap { inner } 90 | } 91 | } 92 | 93 | impl NEMap { 94 | /// Attempt a conversion from [`HashMap`], consuming the given `HashMap`. 95 | /// Will return `None` if the `HashMap` is empty. 96 | /// 97 | /// ``` 98 | /// use std::collections::*; 99 | /// 100 | /// use nonempty_collections::*; 101 | /// 102 | /// let mut map = HashMap::new(); 103 | /// map.extend([("a", 1), ("b", 2)]); 104 | /// assert_eq!(Some(nem! {"a" => 1, "b" => 2}), NEMap::try_from_map(map)); 105 | /// let map: HashMap<(), ()> = HashMap::new(); 106 | /// assert_eq!(None, NEMap::try_from_map(map)); 107 | /// ``` 108 | #[must_use] 109 | pub fn try_from_map(map: HashMap) -> Option { 110 | if map.is_empty() { 111 | None 112 | } else { 113 | Some(Self { inner: map }) 114 | } 115 | } 116 | 117 | /// Returns the number of elements the map can hold without reallocating. 118 | #[must_use] 119 | pub fn capacity(&self) -> NonZeroUsize { 120 | unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) } 121 | } 122 | 123 | /// Returns a reference to the map's `BuildHasher`. 124 | #[must_use] 125 | pub fn hasher(&self) -> &S { 126 | self.inner.hasher() 127 | } 128 | 129 | /// Returns a regular iterator over the entries in this non-empty map. 130 | /// 131 | /// For a `NonEmptyIterator` see `Self::nonempty_iter()`. 132 | pub fn iter(&self) -> std::collections::hash_map::Iter<'_, K, V> { 133 | self.inner.iter() 134 | } 135 | 136 | /// Returns a regular mutable iterator over the entries in this non-empty 137 | /// map. 138 | /// 139 | /// For a `NonEmptyIterator` see `Self::nonempty_iter_mut()`. 140 | pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<'_, K, V> { 141 | self.inner.iter_mut() 142 | } 143 | 144 | /// An iterator visiting all elements in arbitrary order. The iterator 145 | /// element type is `(&'a K, &'a V)`. 146 | pub fn nonempty_iter(&self) -> Iter<'_, K, V> { 147 | Iter { 148 | iter: self.inner.iter(), 149 | } 150 | } 151 | 152 | /// An iterator visiting all elements in arbitrary order. The iterator 153 | /// element type is `(&'a K, &'a mut V)`. 154 | /// 155 | /// # Panics 156 | /// 157 | /// If you manually advance this iterator until empty and then call `first`, 158 | /// you're in for a surprise. 159 | pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, K, V> { 160 | IterMut { 161 | iter: self.inner.iter_mut(), 162 | } 163 | } 164 | 165 | /// An iterator visiting all keys in arbitrary order. The iterator element 166 | /// type is `&'a K`. 167 | /// 168 | /// ``` 169 | /// use nonempty_collections::*; 170 | /// 171 | /// let m = nem!["Valmar" => "Vanyar", "Tirion" => "Noldor", "Alqualondë" => "Teleri"]; 172 | /// let mut v: NEVec<_> = m.keys().collect(); 173 | /// v.sort(); 174 | /// assert_eq!(nev![&"Alqualondë", &"Tirion", &"Valmar"], v); 175 | /// ``` 176 | pub fn keys(&self) -> Keys<'_, K, V> { 177 | Keys { 178 | inner: self.inner.keys(), 179 | } 180 | } 181 | 182 | /// Returns the number of elements in the map. Always 1 or more. 183 | /// 184 | /// ``` 185 | /// use nonempty_collections::nem; 186 | /// 187 | /// let m = nem!["a" => 1, "b" => 2]; 188 | /// assert_eq!(2, m.len().get()); 189 | /// ``` 190 | #[must_use] 191 | pub fn len(&self) -> NonZeroUsize { 192 | unsafe { NonZeroUsize::new_unchecked(self.inner.len()) } 193 | } 194 | 195 | /// A `NEMap` is never empty. 196 | #[deprecated(since = "0.1.0", note = "A NEMap is never empty.")] 197 | #[must_use] 198 | pub const fn is_empty(&self) -> bool { 199 | false 200 | } 201 | 202 | /// An iterator visiting all values in arbitrary order. The iterator element 203 | /// type is `&'a V`. 204 | /// 205 | /// ``` 206 | /// use nonempty_collections::*; 207 | /// 208 | /// let m = nem!["Valmar" => "Vanyar", "Tirion" => "Noldor", "Alqualondë" => "Teleri"]; 209 | /// let mut v: NEVec<_> = m.values().collect(); 210 | /// v.sort(); 211 | /// assert_eq!(nev![&"Noldor", &"Teleri", &"Vanyar"], v); 212 | /// ``` 213 | pub fn values(&self) -> Values<'_, K, V> { 214 | Values { 215 | inner: self.inner.values(), 216 | } 217 | } 218 | 219 | // /// An iterator visiting all values mutably in arbitrary order. The iterator 220 | // /// element type is `&'a mut V`. 221 | // /// 222 | // /// ``` 223 | // /// use nonempty_collections::nem; 224 | // /// 225 | // /// let mut m = nem!["Valmar" => 10000, "Tirion" => 10000, "Alqualondë" => 226 | // 10000]; /// 227 | // /// for v in m.values_mut() { 228 | // /// *v += 1000; 229 | // /// } 230 | // /// ``` 231 | // pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { 232 | // ValuesMut { 233 | // inner: self.iter_mut(), 234 | // head_val: todo!(), 235 | // } 236 | // } 237 | } 238 | 239 | impl NEMap 240 | where 241 | K: Eq + Hash, 242 | S: BuildHasher, 243 | { 244 | /// Returns true if the map contains a value. 245 | /// 246 | /// ``` 247 | /// use nonempty_collections::nem; 248 | /// 249 | /// let m = nem!["Jack" => 8]; 250 | /// assert!(m.contains_key("Jack")); 251 | /// assert!(!m.contains_key("Colin")); 252 | /// ``` 253 | #[must_use] 254 | pub fn contains_key(&self, k: &Q) -> bool 255 | where 256 | K: Borrow, 257 | Q: Eq + Hash + ?Sized, 258 | { 259 | self.inner.contains_key(k) 260 | } 261 | 262 | /// Returns a reference to the value corresponding to the key. 263 | /// 264 | /// The key may be any borrowed form of the map's value type, but `Hash` and 265 | /// `Eq` on the borrowed form must match those for the key type. 266 | /// 267 | /// ``` 268 | /// use nonempty_collections::nem; 269 | /// 270 | /// let m = nem!["silmarils" => 3]; 271 | /// assert_eq!(Some(&3), m.get("silmarils")); 272 | /// assert_eq!(None, m.get("arkenstone")); 273 | /// ``` 274 | #[must_use] 275 | pub fn get(&self, k: &Q) -> Option<&V> 276 | where 277 | K: Borrow, 278 | Q: Eq + Hash + ?Sized, 279 | { 280 | self.inner.get(k) 281 | } 282 | 283 | /// Returns the key-value pair corresponding to the key. 284 | /// 285 | /// The key may be any borrowed form of the map's value type, but `Hash` and 286 | /// `Eq` on the borrowed form must match those for the key type. 287 | /// 288 | /// ``` 289 | /// use nonempty_collections::nem; 290 | /// 291 | /// let m = nem!["silmarils" => 3]; 292 | /// assert_eq!(Some((&"silmarils", &3)), m.get_key_value("silmarils")); 293 | /// assert_eq!(None, m.get_key_value("arkenstone")); 294 | /// ``` 295 | #[must_use] 296 | pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> 297 | where 298 | K: Borrow, 299 | Q: Eq + Hash + ?Sized, 300 | { 301 | self.inner.get_key_value(k) 302 | } 303 | 304 | /// Returns a reference to the value corresponding to the key. 305 | /// 306 | /// The key may be any borrowed form of the map's value type, but `Hash` and 307 | /// `Eq` on the borrowed form must match those for the key type. 308 | /// 309 | /// ``` 310 | /// use nonempty_collections::nem; 311 | /// 312 | /// let mut m = nem!["silmarils" => 3]; 313 | /// let mut v = m.get_mut("silmarils").unwrap(); 314 | /// 315 | /// // And thus it came to pass that the Silmarils found their long homes: 316 | /// // one in the airs of heaven, and one in the fires of the heart of the 317 | /// // world, and one in the deep waters. 318 | /// *v -= 3; 319 | /// 320 | /// assert_eq!(Some(&0), m.get("silmarils")); 321 | /// ``` 322 | #[must_use] 323 | pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> 324 | where 325 | K: Borrow, 326 | Q: Eq + Hash + ?Sized, 327 | { 328 | self.inner.get_mut(k) 329 | } 330 | 331 | /// Insert a key-value pair into the map. 332 | /// 333 | /// If the map did not have this present, [`None`] is returned. 334 | /// 335 | /// If the map did have this key present, the value is updated, and the old 336 | /// value is returned. The key is not updated, though; this matters for 337 | /// types that can be `==` without being identical. See [`HashMap::insert`] 338 | /// for more. 339 | /// 340 | /// ``` 341 | /// use nonempty_collections::nem; 342 | /// 343 | /// let mut m = nem!["Vilya" => "Elrond", "Nenya" => "Galadriel"]; 344 | /// assert_eq!(None, m.insert("Narya", "Cirdan")); 345 | /// 346 | /// // The Ring of Fire was given to Gandalf upon his arrival in Middle Earth. 347 | /// assert_eq!(Some("Cirdan"), m.insert("Narya", "Gandalf")); 348 | /// ``` 349 | pub fn insert(&mut self, k: K, v: V) -> Option { 350 | self.inner.insert(k, v) 351 | } 352 | 353 | /// Shrinks the capacity of the map as much as possible. It will drop down 354 | /// as much as possible while maintaining the internal rules and possibly 355 | /// leaving some space in accordance with the resize policy. 356 | pub fn shrink_to_fit(&mut self) { 357 | self.inner.shrink_to_fit(); 358 | } 359 | 360 | /// See [`HashMap::with_capacity_and_hasher`]. 361 | #[must_use] 362 | pub fn with_capacity_and_hasher( 363 | capacity: NonZeroUsize, 364 | hasher: S, 365 | k: K, 366 | v: V, 367 | ) -> NEMap { 368 | let mut inner = HashMap::with_capacity_and_hasher(capacity.get(), hasher); 369 | inner.insert(k, v); 370 | NEMap { inner } 371 | } 372 | 373 | /// See [`HashMap::with_hasher`]. 374 | #[must_use] 375 | pub fn with_hasher(hasher: S, k: K, v: V) -> NEMap { 376 | let mut inner = HashMap::with_hasher(hasher); 377 | inner.insert(k, v); 378 | NEMap { inner } 379 | } 380 | } 381 | 382 | impl PartialEq for NEMap 383 | where 384 | K: Eq + Hash, 385 | V: Eq, 386 | S: BuildHasher, 387 | { 388 | /// This is an `O(n)` comparison of each key/value pair, one by one. 389 | /// Short-circuits if any comparison fails. 390 | /// 391 | /// ``` 392 | /// use nonempty_collections::*; 393 | /// 394 | /// let m0 = nem!['a' => 1, 'b' => 2]; 395 | /// let m1 = nem!['b' => 2, 'a' => 1]; 396 | /// assert_eq!(m0, m1); 397 | /// ``` 398 | fn eq(&self, other: &Self) -> bool { 399 | self.inner.eq(&other.inner) 400 | } 401 | } 402 | 403 | impl Eq for NEMap 404 | where 405 | K: Eq + Hash, 406 | V: Eq, 407 | S: BuildHasher, 408 | { 409 | } 410 | 411 | impl From> for HashMap 412 | where 413 | K: Eq + Hash, 414 | S: BuildHasher, 415 | { 416 | /// ``` 417 | /// use nonempty_collections::nem; 418 | /// use std::collections::HashMap; 419 | /// 420 | /// let m: HashMap<&str, usize> = nem!["population" => 1000].into(); 421 | /// assert!(m.contains_key("population")); 422 | /// ``` 423 | fn from(m: NEMap) -> Self { 424 | m.inner 425 | } 426 | } 427 | 428 | impl TryFrom> for NEMap 429 | where 430 | K: Eq + Hash, 431 | S: BuildHasher + Default, 432 | { 433 | type Error = crate::Error; 434 | 435 | fn try_from(map: HashMap) -> Result { 436 | map.try_into_nonempty_iter() 437 | .map(NonEmptyIterator::collect) 438 | .ok_or(crate::Error::Empty) 439 | } 440 | } 441 | 442 | impl IntoNonEmptyIterator for NEMap { 443 | type IntoNEIter = IntoIter; 444 | 445 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 446 | IntoIter { 447 | iter: self.inner.into_iter(), 448 | } 449 | } 450 | } 451 | 452 | impl<'a, K, V, S> IntoNonEmptyIterator for &'a NEMap { 453 | type IntoNEIter = Iter<'a, K, V>; 454 | 455 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 456 | self.nonempty_iter() 457 | } 458 | } 459 | 460 | impl IntoIterator for NEMap { 461 | type Item = (K, V); 462 | 463 | type IntoIter = std::collections::hash_map::IntoIter; 464 | 465 | fn into_iter(self) -> Self::IntoIter { 466 | self.inner.into_iter() 467 | } 468 | } 469 | 470 | impl<'a, K, V, S> IntoIterator for &'a NEMap { 471 | type Item = (&'a K, &'a V); 472 | 473 | type IntoIter = std::collections::hash_map::Iter<'a, K, V>; 474 | 475 | fn into_iter(self) -> Self::IntoIter { 476 | self.iter() 477 | } 478 | } 479 | 480 | impl<'a, K, V, S> IntoIterator for &'a mut NEMap { 481 | type Item = (&'a K, &'a mut V); 482 | 483 | type IntoIter = std::collections::hash_map::IterMut<'a, K, V>; 484 | 485 | fn into_iter(self) -> Self::IntoIter { 486 | self.iter_mut() 487 | } 488 | } 489 | 490 | /// ``` 491 | /// use nonempty_collections::*; 492 | /// 493 | /// let v = nev![('a', 1), ('b', 2), ('c', 3), ('a', 4)]; 494 | /// let m0: NEMap<_, _> = v.into_nonempty_iter().collect(); 495 | /// let m1: NEMap<_, _> = nem!['a' => 4, 'b' => 2, 'c' => 3]; 496 | /// assert_eq!(m0, m1); 497 | /// ``` 498 | impl FromNonEmptyIterator<(K, V)> for NEMap 499 | where 500 | K: Eq + Hash, 501 | S: BuildHasher + Default, 502 | { 503 | fn from_nonempty_iter(iter: I) -> Self 504 | where 505 | I: IntoNonEmptyIterator, 506 | { 507 | NEMap { 508 | inner: iter.into_nonempty_iter().into_iter().collect(), 509 | } 510 | } 511 | } 512 | 513 | /// A non-empty iterator over the entries of an [`NEMap`]. 514 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 515 | pub struct Iter<'a, K: 'a, V: 'a> { 516 | iter: std::collections::hash_map::Iter<'a, K, V>, 517 | } 518 | 519 | impl NonEmptyIterator for Iter<'_, K, V> {} 520 | 521 | impl<'a, K, V> IntoIterator for Iter<'a, K, V> { 522 | type Item = (&'a K, &'a V); 523 | 524 | type IntoIter = std::collections::hash_map::Iter<'a, K, V>; 525 | 526 | fn into_iter(self) -> Self::IntoIter { 527 | self.iter 528 | } 529 | } 530 | 531 | impl fmt::Debug for Iter<'_, K, V> { 532 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 533 | self.iter.fmt(f) 534 | } 535 | } 536 | 537 | /// A non-empty iterator over mutable values of an [`NEMap`]. 538 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 539 | pub struct IterMut<'a, K: 'a, V: 'a> { 540 | iter: std::collections::hash_map::IterMut<'a, K, V>, 541 | } 542 | 543 | impl NonEmptyIterator for IterMut<'_, K, V> {} 544 | 545 | impl<'a, K, V> IntoIterator for IterMut<'a, K, V> { 546 | type Item = (&'a K, &'a mut V); 547 | 548 | type IntoIter = std::collections::hash_map::IterMut<'a, K, V>; 549 | 550 | fn into_iter(self) -> Self::IntoIter { 551 | self.iter 552 | } 553 | } 554 | 555 | impl fmt::Debug for IterMut<'_, K, V> { 556 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 557 | self.iter.fmt(f) 558 | } 559 | } 560 | 561 | /// A non-empty iterator over the entries of an [`NEMap`]. 562 | pub struct IntoIter { 563 | iter: std::collections::hash_map::IntoIter, 564 | } 565 | 566 | impl NonEmptyIterator for IntoIter {} 567 | 568 | impl IntoIterator for IntoIter { 569 | type Item = (K, V); 570 | 571 | type IntoIter = std::collections::hash_map::IntoIter; 572 | 573 | fn into_iter(self) -> Self::IntoIter { 574 | self.iter 575 | } 576 | } 577 | 578 | impl fmt::Debug for IntoIter { 579 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 580 | self.iter.fmt(f) 581 | } 582 | } 583 | 584 | /// A non-empty iterator over the keys of an [`NEMap`]. 585 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 586 | pub struct Keys<'a, K: 'a, V: 'a> { 587 | inner: std::collections::hash_map::Keys<'a, K, V>, 588 | } 589 | 590 | impl NonEmptyIterator for Keys<'_, K, V> {} 591 | 592 | impl<'a, K, V> IntoIterator for Keys<'a, K, V> { 593 | type Item = &'a K; 594 | 595 | type IntoIter = std::collections::hash_map::Keys<'a, K, V>; 596 | 597 | fn into_iter(self) -> Self::IntoIter { 598 | self.inner 599 | } 600 | } 601 | 602 | impl fmt::Debug for Keys<'_, K, V> { 603 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 604 | self.inner.fmt(f) 605 | } 606 | } 607 | 608 | /// A non-empty iterator over the values of an [`NEMap`]. 609 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 610 | pub struct Values<'a, K: 'a, V: 'a> { 611 | inner: std::collections::hash_map::Values<'a, K, V>, 612 | } 613 | 614 | impl NonEmptyIterator for Values<'_, K, V> {} 615 | 616 | impl<'a, K, V> IntoIterator for Values<'a, K, V> { 617 | type Item = &'a V; 618 | 619 | type IntoIter = std::collections::hash_map::Values<'a, K, V>; 620 | 621 | fn into_iter(self) -> Self::IntoIter { 622 | self.inner 623 | } 624 | } 625 | 626 | impl fmt::Debug for Values<'_, K, V> { 627 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 628 | self.inner.fmt(f) 629 | } 630 | } 631 | 632 | impl fmt::Debug for NEMap { 633 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 634 | self.inner.fmt(f) 635 | } 636 | } 637 | 638 | // /// A non-empty iterator over mutable values of an [`NEMap`]. 639 | // pub struct ValuesMut<'a, K: 'a, V: 'a> { 640 | // inner: IterMut<'a, K, V>, 641 | // } 642 | 643 | // impl<'a, K, V> NonEmptyIterator for ValuesMut<'a, K, V> { 644 | // type Item = &'a mut V; 645 | 646 | // type Iter = Skip, 647 | // std::collections::hash_map::IterMut<'a, K, V>>>; 648 | 649 | // fn first(self) -> (Self::Item, Self::Iter) { 650 | // (self.head_val, self.inner.skip(1)) 651 | // } 652 | 653 | // fn next(&mut self) -> Option { 654 | // self.inner.next().map(|(_, v)| v) 655 | // } 656 | // } 657 | 658 | #[cfg(test)] 659 | mod test { 660 | use std::num::NonZeroUsize; 661 | 662 | use maplit::hashmap; 663 | 664 | use crate::nem; 665 | 666 | struct Foo { 667 | user: String, 668 | } 669 | 670 | #[test] 671 | fn debug_impl() { 672 | let expected = format!("{:?}", hashmap! {0 => 10}); 673 | let actual = format!("{:?}", nem! {0 => 10}); 674 | assert_eq!(expected, actual); 675 | } 676 | 677 | #[test] 678 | fn macro_usage() { 679 | let a = Foo { 680 | user: "a".to_string(), 681 | }; 682 | let b = Foo { 683 | user: "b".to_string(), 684 | }; 685 | 686 | let map = nem![1 => a, 2 => b]; 687 | assert_eq!("a", map.get(&1).unwrap().user); 688 | assert_eq!("b", map.get(&2).unwrap().user); 689 | } 690 | 691 | #[test] 692 | fn macro_length() { 693 | let map = nem![1 => 'a', 2 => 'b', 1 => 'c']; 694 | assert_eq!(unsafe { NonZeroUsize::new_unchecked(2) }, map.len()); 695 | assert_eq!('c', *map.get(&1).unwrap()); 696 | assert_eq!('b', *map.get(&2).unwrap()); 697 | } 698 | 699 | #[test] 700 | fn iter_mut() { 701 | let mut v = nem! {"a" => 0, "b" => 1, "c" => 2}; 702 | 703 | v.iter_mut().for_each(|(_k, v)| { 704 | *v += 1; 705 | }); 706 | assert_eq!(nem! {"a" => 1, "b" => 2, "c" => 3}, v); 707 | 708 | for (_k, v) in &mut v { 709 | *v -= 1; 710 | } 711 | assert_eq!(nem! {"a" => 0, "b" => 1, "c" => 2}, v); 712 | } 713 | } 714 | 715 | #[cfg(feature = "serde")] 716 | #[cfg(test)] 717 | mod serde_tests { 718 | use std::collections::HashMap; 719 | 720 | use crate::nem; 721 | use crate::NEMap; 722 | 723 | #[test] 724 | fn json() { 725 | let map0 = nem![1 => 'a', 2 => 'b', 1 => 'c']; 726 | let j = serde_json::to_string(&map0).unwrap(); 727 | let map1 = serde_json::from_str(&j).unwrap(); 728 | assert_eq!(map0, map1); 729 | 730 | let empty: HashMap = HashMap::new(); 731 | let j = serde_json::to_string(&empty).unwrap(); 732 | let bad = serde_json::from_str::>(&j); 733 | assert!(bad.is_err()); 734 | } 735 | } 736 | -------------------------------------------------------------------------------- /src/set.rs: -------------------------------------------------------------------------------- 1 | //! Non-empty Sets. 2 | 3 | use core::fmt; 4 | use std::borrow::Borrow; 5 | use std::collections::HashSet; 6 | use std::hash::BuildHasher; 7 | use std::hash::Hash; 8 | use std::num::NonZeroUsize; 9 | 10 | #[cfg(feature = "serde")] 11 | use serde::Deserialize; 12 | #[cfg(feature = "serde")] 13 | use serde::Serialize; 14 | 15 | use crate::iter::NonEmptyIterator; 16 | use crate::FromNonEmptyIterator; 17 | use crate::IntoIteratorExt; 18 | use crate::IntoNonEmptyIterator; 19 | 20 | /// Like the [`crate::nev!`] macro, but for Sets. A nice short-hand for 21 | /// constructing [`NESet`] values. 22 | /// 23 | /// ``` 24 | /// use nonempty_collections::nes; 25 | /// 26 | /// let s = nes![1, 2, 2, 3,]; 27 | /// assert_eq!(3, s.len().get()); 28 | /// ``` 29 | #[macro_export] 30 | macro_rules! nes { 31 | ($h:expr, $( $x:expr ),* $(,)?) => {{ 32 | let mut set = $crate::NESet::new($h); 33 | $( set.insert($x); )* 34 | set 35 | }}; 36 | ($h:expr) => { 37 | $crate::NESet::new($h) 38 | } 39 | } 40 | 41 | /// A non-empty, growable `HashSet`. 42 | /// 43 | /// # Construction and Access 44 | /// 45 | /// The [`nes`] macro is the simplest way to construct an `NESet`: 46 | /// 47 | /// ``` 48 | /// use nonempty_collections::*; 49 | /// 50 | /// let s = nes![1, 1, 2, 2, 3, 3, 4, 4]; 51 | /// let mut v: NEVec<_> = s.nonempty_iter().collect(); 52 | /// v.sort(); 53 | /// assert_eq!(nev![&1, &2, &3, &4], v); 54 | /// ``` 55 | /// 56 | /// 57 | /// ``` 58 | /// use nonempty_collections::nes; 59 | /// 60 | /// let s = nes!["Fëanor", "Fingolfin", "Finarfin"]; 61 | /// assert!(s.contains(&"Fëanor")); 62 | /// ``` 63 | /// 64 | /// # Conversion 65 | /// 66 | /// If you have a [`HashSet`] but want an `NESet`, try [`NESet::try_from_set`]. 67 | /// Naturally, this might not succeed. 68 | /// 69 | /// If you have an `NESet` but want a `HashSet`, try their corresponding 70 | /// [`From`] instance. This will always succeed. 71 | /// 72 | /// ``` 73 | /// use std::collections::HashSet; 74 | /// 75 | /// use nonempty_collections::nes; 76 | /// 77 | /// let n0 = nes![1, 2, 3]; 78 | /// let s0 = HashSet::from(n0); 79 | /// 80 | /// // Or just use `Into`. 81 | /// let n1 = nes![1, 2, 3]; 82 | /// let s1: HashSet<_> = n1.into(); 83 | /// ``` 84 | /// 85 | /// # API Differences with [`HashSet`] 86 | /// 87 | /// Note that the following methods aren't implemented for `NESet`: 88 | /// 89 | /// - `clear` 90 | /// - `drain` 91 | /// - `drain_filter` 92 | /// - `remove` 93 | /// - `retain` 94 | /// - `take` 95 | /// 96 | /// As these methods are all "mutate-in-place" style and are difficult to 97 | /// reconcile with the non-emptiness guarantee. 98 | #[allow(clippy::unsafe_derive_deserialize)] 99 | #[cfg_attr( 100 | feature = "serde", 101 | derive(Serialize, Deserialize), 102 | serde(bound( 103 | serialize = "T: Eq + Hash + Clone + Serialize, S: Clone + BuildHasher", 104 | deserialize = "T: Eq + Hash + Deserialize<'de>, S: Default + BuildHasher" 105 | )), 106 | serde(into = "HashSet", try_from = "HashSet") 107 | )] 108 | #[derive(Clone)] 109 | pub struct NESet { 110 | inner: HashSet, 111 | } 112 | 113 | impl NESet { 114 | /// Returns the number of elements the set can hold without reallocating. 115 | #[must_use] 116 | pub fn capacity(&self) -> NonZeroUsize { 117 | unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) } 118 | } 119 | 120 | /// Returns a reference to the set's `BuildHasher`. 121 | #[must_use] 122 | pub fn hasher(&self) -> &S { 123 | self.inner.hasher() 124 | } 125 | 126 | /// Returns a regular iterator over the values in this non-empty set. 127 | /// 128 | /// For a `NonEmptyIterator` see `Self::nonempty_iter()`. 129 | pub fn iter(&self) -> std::collections::hash_set::Iter<'_, T> { 130 | self.inner.iter() 131 | } 132 | 133 | /// An iterator visiting all elements in arbitrary order. 134 | pub fn nonempty_iter(&self) -> Iter<'_, T> { 135 | Iter { 136 | iter: self.inner.iter(), 137 | } 138 | } 139 | 140 | /// Returns the number of elements in the set. Always 1 or more. 141 | /// 142 | /// ``` 143 | /// use nonempty_collections::nes; 144 | /// 145 | /// let s = nes![1, 2, 3]; 146 | /// assert_eq!(3, s.len().get()); 147 | /// ``` 148 | #[must_use] 149 | pub fn len(&self) -> NonZeroUsize { 150 | unsafe { NonZeroUsize::new_unchecked(self.inner.len()) } 151 | } 152 | 153 | /// A `NESet` is never empty. 154 | #[deprecated(since = "0.1.0", note = "A NESet is never empty.")] 155 | #[must_use] 156 | pub const fn is_empty(&self) -> bool { 157 | false 158 | } 159 | } 160 | 161 | impl NESet 162 | where 163 | T: Eq + Hash, 164 | { 165 | /// Creates a new `NESet` with a single element. 166 | #[must_use] 167 | pub fn new(value: T) -> Self { 168 | let mut inner = HashSet::new(); 169 | inner.insert(value); 170 | Self { inner } 171 | } 172 | 173 | /// Creates a new `NESet` with a single element and specified capacity. 174 | /// 175 | /// ``` 176 | /// use std::hash::RandomState; 177 | /// use std::num::NonZeroUsize; 178 | /// 179 | /// use nonempty_collections::*; 180 | /// let set = NESet::with_capacity(NonZeroUsize::MIN, "hello"); 181 | /// assert_eq!(nes! {"hello"}, set); 182 | /// assert!(set.capacity().get() >= 1); 183 | /// ``` 184 | #[must_use] 185 | pub fn with_capacity(capacity: NonZeroUsize, value: T) -> NESet { 186 | let mut inner = HashSet::with_capacity(capacity.get()); 187 | inner.insert(value); 188 | NESet { inner } 189 | } 190 | } 191 | 192 | impl NESet 193 | where 194 | T: Eq + Hash, 195 | S: BuildHasher, 196 | { 197 | /// Attempt a conversion from a [`HashSet`], consuming the given `HashSet`. 198 | /// Will return `None` if the `HashSet` is empty. 199 | /// 200 | /// ``` 201 | /// use std::collections::HashSet; 202 | /// 203 | /// use nonempty_collections::nes; 204 | /// use nonempty_collections::NESet; 205 | /// 206 | /// let mut s = HashSet::new(); 207 | /// s.extend([1, 2, 3]); 208 | /// 209 | /// let n = NESet::try_from_set(s); 210 | /// assert_eq!(Some(nes![1, 2, 3]), n); 211 | /// let s: HashSet<()> = HashSet::new(); 212 | /// assert_eq!(None, NESet::try_from_set(s)); 213 | /// ``` 214 | #[must_use] 215 | pub fn try_from_set(set: HashSet) -> Option> { 216 | if set.is_empty() { 217 | None 218 | } else { 219 | Some(NESet { inner: set }) 220 | } 221 | } 222 | 223 | /// Returns true if the set contains a value. 224 | /// 225 | /// ``` 226 | /// use nonempty_collections::nes; 227 | /// 228 | /// let s = nes![1, 2, 3]; 229 | /// assert!(s.contains(&3)); 230 | /// assert!(!s.contains(&10)); 231 | /// ``` 232 | #[must_use] 233 | pub fn contains(&self, value: &Q) -> bool 234 | where 235 | T: Borrow, 236 | Q: Eq + Hash + ?Sized, 237 | { 238 | self.inner.contains(value) 239 | } 240 | 241 | /// Visits the values representing the difference, i.e., the values that are 242 | /// in `self` but not in `other`. 243 | /// 244 | /// ``` 245 | /// use nonempty_collections::nes; 246 | /// 247 | /// let s0 = nes![1, 2, 3]; 248 | /// let s1 = nes![3, 4, 5]; 249 | /// let mut v: Vec<_> = s0.difference(&s1).collect(); 250 | /// v.sort(); 251 | /// assert_eq!(vec![&1, &2], v); 252 | /// ``` 253 | pub fn difference<'a>( 254 | &'a self, 255 | other: &'a NESet, 256 | ) -> std::collections::hash_set::Difference<'a, T, S> { 257 | self.inner.difference(&other.inner) 258 | } 259 | 260 | /// Returns a reference to the value in the set, if any, that is equal to 261 | /// the given value. 262 | /// 263 | /// The value may be any borrowed form of the set’s value type, but `Hash` 264 | /// and `Eq` on the borrowed form must match those for the value type. 265 | /// 266 | /// ``` 267 | /// use nonempty_collections::nes; 268 | /// 269 | /// let s = nes![1, 2, 3]; 270 | /// assert_eq!(Some(&3), s.get(&3)); 271 | /// assert_eq!(None, s.get(&10)); 272 | /// ``` 273 | #[must_use] 274 | pub fn get(&self, value: &Q) -> Option<&T> 275 | where 276 | T: Borrow, 277 | Q: Eq + Hash, 278 | { 279 | self.inner.get(value) 280 | } 281 | 282 | /// Adds a value to the set. 283 | /// 284 | /// If the set did not have this value present, `true` is returned. 285 | /// 286 | /// If the set did have this value present, `false` is returned. 287 | /// 288 | /// ``` 289 | /// use nonempty_collections::nes; 290 | /// 291 | /// let mut s = nes![1, 2, 3]; 292 | /// assert_eq!(false, s.insert(2)); 293 | /// assert_eq!(true, s.insert(4)); 294 | /// ``` 295 | pub fn insert(&mut self, value: T) -> bool { 296 | self.inner.insert(value) 297 | } 298 | 299 | /// Visits the values representing the interesection, i.e., the values that 300 | /// are both in `self` and `other`. 301 | /// 302 | /// ``` 303 | /// use nonempty_collections::nes; 304 | /// 305 | /// let s0 = nes![1, 2, 3]; 306 | /// let s1 = nes![3, 4, 5]; 307 | /// let mut v: Vec<_> = s0.intersection(&s1).collect(); 308 | /// v.sort(); 309 | /// assert_eq!(vec![&3], v); 310 | /// ``` 311 | pub fn intersection<'a>( 312 | &'a self, 313 | other: &'a NESet, 314 | ) -> std::collections::hash_set::Intersection<'a, T, S> { 315 | self.inner.intersection(&other.inner) 316 | } 317 | 318 | /// Returns `true` if `self` has no elements in common with `other`. 319 | /// This is equivalent to checking for an empty intersection. 320 | /// 321 | /// ``` 322 | /// use nonempty_collections::nes; 323 | /// 324 | /// let s0 = nes![1, 2, 3]; 325 | /// let s1 = nes![4, 5, 6]; 326 | /// assert!(s0.is_disjoint(&s1)); 327 | /// ``` 328 | #[must_use] 329 | pub fn is_disjoint(&self, other: &NESet) -> bool { 330 | self.inner.is_disjoint(&other.inner) 331 | } 332 | 333 | /// Returns `true` if the set is a subset of another, i.e., `other` contains 334 | /// at least all the values in `self`. 335 | /// 336 | /// ``` 337 | /// use nonempty_collections::nes; 338 | /// 339 | /// let sub = nes![1, 2, 3]; 340 | /// let sup = nes![1, 2, 3, 4]; 341 | /// 342 | /// assert!(sub.is_subset(&sup)); 343 | /// assert!(!sup.is_subset(&sub)); 344 | /// ``` 345 | #[must_use] 346 | pub fn is_subset(&self, other: &NESet) -> bool { 347 | self.inner.is_subset(&other.inner) 348 | } 349 | 350 | /// Returns `true` if the set is a superset of another, i.e., `self` 351 | /// contains at least all the values in `other`. 352 | /// 353 | /// ``` 354 | /// use nonempty_collections::nes; 355 | /// 356 | /// let sub = nes![1, 2, 3]; 357 | /// let sup = nes![1, 2, 3, 4]; 358 | /// 359 | /// assert!(sup.is_superset(&sub)); 360 | /// assert!(!sub.is_superset(&sup)); 361 | /// ``` 362 | #[must_use] 363 | pub fn is_superset(&self, other: &NESet) -> bool { 364 | self.inner.is_superset(&other.inner) 365 | } 366 | 367 | /// Adds a value to the set, replacing the existing value, if any, that is 368 | /// equal to the given one. Returns the replaced value. 369 | pub fn replace(&mut self, value: T) -> Option { 370 | self.inner.replace(value) 371 | } 372 | 373 | /// Reserves capacity for at least `additional` more elements to be inserted 374 | /// in the `NESet`. The collection may reserve more space to avoid frequent 375 | /// reallocations. 376 | /// 377 | /// # Panics 378 | /// 379 | /// Panics if the new allocation size overflows `usize`. 380 | pub fn reserve(&mut self, additional: usize) { 381 | self.inner.reserve(additional); 382 | } 383 | 384 | /// Shrinks the capacity of the set as much as possible. It will drop down 385 | /// as much as possible while maintaining the internal rules and possibly 386 | /// leaving some space in accordance with the resize policy. 387 | pub fn shrink_to_fit(&mut self) { 388 | self.inner.shrink_to_fit(); 389 | } 390 | 391 | /// Visits the values representing the union, i.e., all the values in `self` 392 | /// or `other`, without duplicates. 393 | /// 394 | /// Note that a Union is always non-empty. 395 | /// 396 | /// ``` 397 | /// use nonempty_collections::*; 398 | /// 399 | /// let s0 = nes![1, 2, 3]; 400 | /// let s1 = nes![3, 4, 5]; 401 | /// let mut v: NEVec<_> = s0.union(&s1).collect(); 402 | /// v.sort(); 403 | /// assert_eq!(nev![&1, &2, &3, &4, &5], v); 404 | /// ``` 405 | pub fn union<'a>(&'a self, other: &'a NESet) -> Union<'a, T, S> { 406 | Union { 407 | inner: self.inner.union(&other.inner), 408 | } 409 | } 410 | 411 | /// See [`HashSet::with_capacity_and_hasher`]. 412 | #[must_use] 413 | pub fn with_capacity_and_hasher(capacity: NonZeroUsize, hasher: S, value: T) -> NESet { 414 | let mut inner = HashSet::with_capacity_and_hasher(capacity.get(), hasher); 415 | inner.insert(value); 416 | NESet { inner } 417 | } 418 | 419 | /// See [`HashSet::with_hasher`]. 420 | #[must_use] 421 | pub fn with_hasher(hasher: S, value: T) -> NESet { 422 | let mut inner = HashSet::with_hasher(hasher); 423 | inner.insert(value); 424 | NESet { inner } 425 | } 426 | } 427 | 428 | impl PartialEq for NESet 429 | where 430 | T: Eq + Hash, 431 | S: BuildHasher, 432 | { 433 | /// ``` 434 | /// use nonempty_collections::nes; 435 | /// 436 | /// let s0 = nes![1, 2, 3]; 437 | /// let s1 = nes![1, 2, 3]; 438 | /// let s2 = nes![1, 2]; 439 | /// let s3 = nes![1, 2, 3, 4]; 440 | /// 441 | /// assert!(s0 == s1); 442 | /// assert!(s0 != s2); 443 | /// assert!(s0 != s3); 444 | /// ``` 445 | fn eq(&self, other: &Self) -> bool { 446 | self.len() == other.len() && self.intersection(other).count() == self.len().get() 447 | } 448 | } 449 | 450 | impl Eq for NESet 451 | where 452 | T: Eq + Hash, 453 | S: BuildHasher, 454 | { 455 | } 456 | 457 | impl IntoNonEmptyIterator for NESet { 458 | type IntoNEIter = IntoIter; 459 | 460 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 461 | IntoIter { 462 | iter: self.inner.into_iter(), 463 | } 464 | } 465 | } 466 | 467 | impl<'a, T, S> IntoNonEmptyIterator for &'a NESet { 468 | type IntoNEIter = Iter<'a, T>; 469 | 470 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 471 | self.nonempty_iter() 472 | } 473 | } 474 | 475 | impl IntoIterator for NESet { 476 | type Item = T; 477 | 478 | type IntoIter = std::collections::hash_set::IntoIter; 479 | 480 | fn into_iter(self) -> Self::IntoIter { 481 | self.inner.into_iter() 482 | } 483 | } 484 | 485 | impl<'a, T, S> IntoIterator for &'a NESet { 486 | type Item = &'a T; 487 | 488 | type IntoIter = std::collections::hash_set::Iter<'a, T>; 489 | 490 | fn into_iter(self) -> Self::IntoIter { 491 | self.iter() 492 | } 493 | } 494 | 495 | /// ``` 496 | /// use nonempty_collections::*; 497 | /// 498 | /// let s0 = nes![1, 2, 3]; 499 | /// let s1: NESet<_> = s0.nonempty_iter().cloned().collect(); 500 | /// assert_eq!(s0, s1); 501 | /// ``` 502 | impl FromNonEmptyIterator for NESet 503 | where 504 | T: Eq + Hash, 505 | S: BuildHasher + Default, 506 | { 507 | /// ``` 508 | /// use nonempty_collections::*; 509 | /// 510 | /// let v = nev![1, 1, 2, 3, 2]; 511 | /// let s = NESet::from_nonempty_iter(v); 512 | /// 513 | /// assert_eq!(nes![1, 2, 3], s); 514 | /// ``` 515 | fn from_nonempty_iter(iter: I) -> Self 516 | where 517 | I: IntoNonEmptyIterator, 518 | { 519 | NESet { 520 | inner: iter.into_nonempty_iter().into_iter().collect(), 521 | } 522 | } 523 | } 524 | 525 | /// A non-empty iterator over the values of an [`NESet`]. 526 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 527 | pub struct Iter<'a, T: 'a> { 528 | iter: std::collections::hash_set::Iter<'a, T>, 529 | } 530 | 531 | impl<'a, T: 'a> IntoIterator for Iter<'a, T> { 532 | type Item = &'a T; 533 | 534 | type IntoIter = std::collections::hash_set::Iter<'a, T>; 535 | 536 | fn into_iter(self) -> Self::IntoIter { 537 | self.iter 538 | } 539 | } 540 | 541 | impl NonEmptyIterator for Iter<'_, T> {} 542 | 543 | impl fmt::Debug for Iter<'_, T> { 544 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 545 | self.iter.fmt(f) 546 | } 547 | } 548 | 549 | /// An owned non-empty iterator over the values of an [`NESet`]. 550 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 551 | pub struct IntoIter { 552 | iter: std::collections::hash_set::IntoIter, 553 | } 554 | 555 | impl IntoIterator for IntoIter { 556 | type Item = T; 557 | 558 | type IntoIter = std::collections::hash_set::IntoIter; 559 | 560 | fn into_iter(self) -> Self::IntoIter { 561 | self.iter 562 | } 563 | } 564 | 565 | impl NonEmptyIterator for IntoIter {} 566 | 567 | impl fmt::Debug for IntoIter { 568 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 569 | self.iter.fmt(f) 570 | } 571 | } 572 | 573 | /// A non-empty iterator producing elements in the union of two [`NESet`]s. 574 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 575 | pub struct Union<'a, T: 'a, S: 'a> { 576 | inner: std::collections::hash_set::Union<'a, T, S>, 577 | } 578 | 579 | impl<'a, T, S> IntoIterator for Union<'a, T, S> 580 | where 581 | T: Eq + Hash, 582 | S: BuildHasher, 583 | { 584 | type Item = &'a T; 585 | 586 | type IntoIter = std::collections::hash_set::Union<'a, T, S>; 587 | 588 | fn into_iter(self) -> Self::IntoIter { 589 | self.inner 590 | } 591 | } 592 | 593 | impl NonEmptyIterator for Union<'_, T, S> 594 | where 595 | T: Eq + Hash, 596 | S: BuildHasher, 597 | { 598 | } 599 | 600 | impl fmt::Debug for Union<'_, T, S> 601 | where 602 | T: fmt::Debug + Eq + Hash, 603 | S: BuildHasher, 604 | { 605 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 606 | self.inner.fmt(f) 607 | } 608 | } 609 | 610 | impl From> for HashSet 611 | where 612 | T: Eq + Hash, 613 | S: BuildHasher, 614 | { 615 | /// ``` 616 | /// use std::collections::HashSet; 617 | /// 618 | /// use nonempty_collections::nes; 619 | /// 620 | /// let s: HashSet<_> = nes![1, 2, 3].into(); 621 | /// let mut v: Vec<_> = s.into_iter().collect(); 622 | /// v.sort(); 623 | /// assert_eq!(vec![1, 2, 3], v); 624 | /// ``` 625 | fn from(s: NESet) -> Self { 626 | s.inner 627 | } 628 | } 629 | 630 | impl fmt::Debug for NESet { 631 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 632 | self.inner.fmt(f) 633 | } 634 | } 635 | 636 | #[cfg(test)] 637 | mod test { 638 | use maplit::hashset; 639 | 640 | #[test] 641 | fn debug_impl() { 642 | let expected = format!("{:?}", hashset! {0}); 643 | let actual = format!("{:?}", nes! {0}); 644 | assert_eq!(expected, actual); 645 | } 646 | 647 | #[test] 648 | fn iter_debug_impl() { 649 | let expected = format!("{:?}", hashset! {0}.iter()); 650 | let actual = format!("{:?}", nes! {0}.nonempty_iter()); 651 | assert_eq!(expected, actual); 652 | } 653 | } 654 | 655 | impl TryFrom> for NESet 656 | where 657 | T: Eq + Hash, 658 | S: BuildHasher + Default, 659 | { 660 | type Error = crate::Error; 661 | 662 | fn try_from(set: HashSet) -> Result { 663 | let ne = set 664 | .try_into_nonempty_iter() 665 | .ok_or(crate::Error::Empty)? 666 | .collect(); 667 | 668 | Ok(ne) 669 | } 670 | } 671 | 672 | #[cfg(feature = "serde")] 673 | #[cfg(test)] 674 | mod serde_tests { 675 | use std::collections::HashSet; 676 | 677 | use crate::nes; 678 | use crate::NESet; 679 | 680 | #[test] 681 | fn json() { 682 | let set0 = nes![1, 1, 2, 3, 2, 1, 4]; 683 | let j = serde_json::to_string(&set0).unwrap(); 684 | let set1 = serde_json::from_str(&j).unwrap(); 685 | assert_eq!(set0, set1); 686 | 687 | let empty: HashSet = HashSet::new(); 688 | let j = serde_json::to_string(&empty).unwrap(); 689 | let bad = serde_json::from_str::>(&j); 690 | assert!(bad.is_err()); 691 | } 692 | } 693 | -------------------------------------------------------------------------------- /src/slice.rs: -------------------------------------------------------------------------------- 1 | //! Non-empty Slices. 2 | 3 | use core::fmt; 4 | use std::iter::FilterMap; 5 | use std::num::NonZeroUsize; 6 | use std::ops::Index; 7 | use std::slice::Chunks; 8 | 9 | use crate::iter::IntoNonEmptyIterator; 10 | use crate::iter::NonEmptyIterator; 11 | 12 | /// A non-empty slice. Like [`crate::NEVec`], but guaranteed to have borrowed 13 | /// contents. 14 | /// 15 | /// [`NESlice::try_from_slice`] is the simplest way to construct this from 16 | /// borrowed data. 17 | /// 18 | /// Unfortunately there is no macro for this, but if you want one, just use 19 | /// `nev!` and handle the ownership manually. Also consider 20 | /// [`crate::NEVec::as_nonempty_slice`]. 21 | /// 22 | /// If you want access to the inner slice, use [`AsRef`]. 23 | #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 24 | pub struct NESlice<'a, T> { 25 | inner: &'a [T], 26 | } 27 | 28 | impl<'a, T> NESlice<'a, T> { 29 | /// Get the first element. Never fails. 30 | #[must_use] 31 | pub const fn first(&self) -> &T { 32 | &self.inner[0] 33 | } 34 | 35 | /// Using `try_from_slice` gives a proof that the input slice is non-empty 36 | /// in the `Some` branch. 37 | #[must_use] 38 | pub const fn try_from_slice(slice: &'a [T]) -> Option { 39 | if slice.is_empty() { 40 | None 41 | } else { 42 | Some(NESlice { inner: slice }) 43 | } 44 | } 45 | 46 | #[must_use] 47 | pub(crate) const fn from_slice_unchecked(slice: &'a [T]) -> Self { 48 | NESlice { inner: slice } 49 | } 50 | 51 | /// Get the length of the slice. 52 | #[must_use] 53 | pub fn len(&self) -> NonZeroUsize { 54 | debug_assert!(!self.inner.is_empty()); 55 | unsafe { NonZeroUsize::new_unchecked(self.inner.len()) } 56 | } 57 | 58 | /// No, this slice is not empty. 59 | #[deprecated(note = "A NESlice is never empty.")] 60 | #[must_use] 61 | pub const fn is_empty(&self) -> bool { 62 | false 63 | } 64 | 65 | /// Returns a regular iterator over the values in this non-empty slice. 66 | /// 67 | /// For a `NonEmptyIterator` see `Self::nonempty_iter()`. 68 | pub fn iter(&self) -> std::slice::Iter<'_, T> { 69 | self.inner.iter() 70 | } 71 | 72 | /// Returns a non-empty iterator. 73 | pub fn nonempty_iter(&self) -> Iter<'_, T> { 74 | Iter { 75 | iter: self.inner.iter(), 76 | } 77 | } 78 | 79 | /// Returns a non-empty iterator over `chunk_size` elements of the `NESlice` 80 | /// at a time, starting at the beginning of the `NESlice`. 81 | /// 82 | /// ``` 83 | /// use std::num::NonZeroUsize; 84 | /// 85 | /// use nonempty_collections::*; 86 | /// 87 | /// let v = nev![1, 2, 3, 4, 5, 6]; 88 | /// let s = v.as_nonempty_slice(); 89 | /// let n = NonZeroUsize::new(2).unwrap(); 90 | /// let r = s.nonempty_chunks(n).collect::>(); 91 | /// 92 | /// let a = nev![1, 2]; 93 | /// let b = nev![3, 4]; 94 | /// let c = nev![5, 6]; 95 | /// 96 | /// assert_eq!( 97 | /// r, 98 | /// nev![ 99 | /// a.as_nonempty_slice(), 100 | /// b.as_nonempty_slice(), 101 | /// c.as_nonempty_slice() 102 | /// ] 103 | /// ); 104 | /// ``` 105 | pub fn nonempty_chunks(&'a self, chunk_size: NonZeroUsize) -> NEChunks<'a, T> { 106 | NEChunks { 107 | inner: self.inner.chunks(chunk_size.get()), 108 | } 109 | } 110 | } 111 | 112 | impl AsRef<[T]> for NESlice<'_, T> { 113 | fn as_ref(&self) -> &[T] { 114 | self.inner 115 | } 116 | } 117 | 118 | impl<'a, T> IntoNonEmptyIterator for NESlice<'a, T> { 119 | type IntoNEIter = Iter<'a, T>; 120 | 121 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 122 | Iter { 123 | iter: self.inner.iter(), 124 | } 125 | } 126 | } 127 | 128 | impl<'a, T> IntoNonEmptyIterator for &'a NESlice<'a, T> { 129 | type IntoNEIter = Iter<'a, T>; 130 | 131 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 132 | self.nonempty_iter() 133 | } 134 | } 135 | 136 | impl<'a, T> IntoIterator for NESlice<'a, T> { 137 | type Item = &'a T; 138 | 139 | type IntoIter = std::slice::Iter<'a, T>; 140 | 141 | fn into_iter(self) -> Self::IntoIter { 142 | self.inner.iter() 143 | } 144 | } 145 | 146 | impl<'a, T> IntoIterator for &'a NESlice<'a, T> { 147 | type Item = &'a T; 148 | 149 | type IntoIter = std::slice::Iter<'a, T>; 150 | 151 | fn into_iter(self) -> Self::IntoIter { 152 | self.iter() 153 | } 154 | } 155 | 156 | impl Index for NESlice<'_, T> { 157 | type Output = T; 158 | 159 | fn index(&self, index: usize) -> &Self::Output { 160 | &self.inner[index] 161 | } 162 | } 163 | 164 | /// A non-empty iterator over the values of an [`NESlice`]. 165 | #[derive(Debug)] 166 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 167 | pub struct Iter<'a, T: 'a> { 168 | iter: std::slice::Iter<'a, T>, 169 | } 170 | 171 | impl NonEmptyIterator for Iter<'_, T> {} 172 | 173 | impl<'a, T> IntoIterator for Iter<'a, T> { 174 | type Item = &'a T; 175 | 176 | type IntoIter = std::slice::Iter<'a, T>; 177 | 178 | fn into_iter(self) -> Self::IntoIter { 179 | self.iter 180 | } 181 | } 182 | 183 | /// A non-empty Iterator of [`NESlice`] chunks. 184 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 185 | pub struct NEChunks<'a, T> { 186 | pub(crate) inner: Chunks<'a, T>, 187 | } 188 | 189 | type SliceFilter<'a, T> = fn(&'a [T]) -> Option>; 190 | 191 | impl NonEmptyIterator for NEChunks<'_, T> {} 192 | 193 | impl<'a, T> IntoIterator for NEChunks<'a, T> { 194 | type Item = NESlice<'a, T>; 195 | 196 | type IntoIter = FilterMap, SliceFilter<'a, T>>; 197 | 198 | fn into_iter(self) -> Self::IntoIter { 199 | self.inner.filter_map(|x| NESlice::try_from_slice(x)) 200 | } 201 | } 202 | 203 | impl fmt::Debug for NEChunks<'_, T> { 204 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 205 | self.inner.fmt(f) 206 | } 207 | } 208 | 209 | #[cfg(test)] 210 | mod tests { 211 | use std::num::NonZeroUsize; 212 | 213 | use crate::nev; 214 | use crate::slice::NEChunks; 215 | use crate::NESlice; 216 | use crate::NEVec; 217 | use crate::NonEmptyIterator; 218 | 219 | #[test] 220 | fn test_from_conversion() { 221 | let slice = [1, 2, 3, 4, 5]; 222 | let nonempty_slice = NESlice::try_from_slice(&slice); 223 | let nonempty_slice = nonempty_slice.unwrap(); 224 | 225 | assert_eq!(nonempty_slice.inner, &[1, 2, 3, 4, 5]); 226 | } 227 | 228 | #[test] 229 | fn test_iter_syntax() { 230 | let slice = [0, 1, 2, 3]; 231 | let nonempty = NESlice::try_from_slice(&slice); 232 | if let Some(nonempty) = nonempty { 233 | for n in &nonempty { 234 | assert_eq!(*n, *n); // Prove that we're dealing with references. 235 | } 236 | } 237 | } 238 | 239 | #[test] 240 | fn test_into_nonempty_iter() { 241 | use crate::IntoNonEmptyIterator; 242 | use crate::NonEmptyIterator; 243 | let slice = [0usize, 1, 2, 3]; 244 | let nonempty = NESlice::try_from_slice(&slice).unwrap(); 245 | for (i, n) in nonempty.into_nonempty_iter().enumerate() { 246 | assert_eq!(i, *n); 247 | } 248 | } 249 | 250 | #[test] 251 | fn chunks() { 252 | let v = nev![1, 2, 3, 4, 5, 6, 7]; 253 | 254 | let n = NonZeroUsize::new(3).unwrap(); 255 | let a: Vec<_> = v.nonempty_chunks(n).collect(); 256 | 257 | assert_eq!( 258 | a, 259 | vec![ 260 | nev![1, 2, 3].as_nonempty_slice(), 261 | nev![4, 5, 6].as_nonempty_slice(), 262 | nev![7].as_nonempty_slice() 263 | ] 264 | ); 265 | 266 | let n = NonZeroUsize::new(1).unwrap(); 267 | let b: Vec<_> = v.nonempty_chunks(n).collect(); 268 | 269 | assert_eq!( 270 | b, 271 | vec![ 272 | nev![1].as_nonempty_slice(), 273 | nev![2].as_nonempty_slice(), 274 | nev![3].as_nonempty_slice(), 275 | nev![4].as_nonempty_slice(), 276 | nev![5].as_nonempty_slice(), 277 | nev![6].as_nonempty_slice(), 278 | nev![7].as_nonempty_slice(), 279 | ] 280 | ); 281 | } 282 | 283 | #[test] 284 | fn chunks_len() { 285 | let v = nev![1, 2, 3]; 286 | let n = NonZeroUsize::new(3).unwrap(); 287 | let c = v.nonempty_chunks(n).count().get(); 288 | assert_eq!(c, 1); 289 | 290 | let v = nev![1, 2, 3]; 291 | let n = NonZeroUsize::new(5).unwrap(); 292 | let c = v.nonempty_chunks(n).count().get(); 293 | assert_eq!(c, 1); 294 | 295 | let v = nev![1, 2, 3, 4]; 296 | let n = NonZeroUsize::new(3).unwrap(); 297 | let c = v.nonempty_chunks(n).count().get(); 298 | assert_eq!(c, 2); 299 | } 300 | 301 | // A test to reproduce index out of range errors 302 | // and ensure that the `NEChunks` iterator works 303 | // as expected. 304 | #[test] 305 | fn chunks_into_iter_with_chunk_size_over_len() { 306 | let v = nev![1, 2, 3]; 307 | let n = NonZeroUsize::new(4).unwrap(); 308 | let c = v.nonempty_chunks(n); 309 | 310 | // Iterating over should not produce any errors. 311 | for slice in c { 312 | let _: NESlice<'_, i32> = slice; 313 | } 314 | 315 | let v = nev![1, 2, 3]; 316 | let n = NonZeroUsize::new(4).unwrap(); 317 | let c: NEVec<_> = v.nonempty_chunks(n).collect(); 318 | 319 | assert_eq!(1, c.len().get()); 320 | assert_eq!(&v.as_nonempty_slice(), c.first()); 321 | } 322 | 323 | // A test to ensure the correctness of the `NEChunks` iterator 324 | #[test] 325 | fn chunks_into_iter_should_return_elements_exactly_once() { 326 | let v = nev![1, 2, 3, 4, 5, 6, 57]; 327 | let n = NonZeroUsize::new(3).unwrap(); 328 | let c: NEChunks<'_, i32> = v.nonempty_chunks(n); 329 | 330 | let mut r: Vec> = vec![]; 331 | 332 | for slice in c { 333 | let _: NESlice<'_, i32> = slice; 334 | r.push(slice); 335 | } 336 | 337 | assert_eq!( 338 | r, 339 | vec![ 340 | nev![1, 2, 3].as_nonempty_slice(), 341 | nev![4, 5, 6].as_nonempty_slice(), 342 | nev![57].as_nonempty_slice(), 343 | ] 344 | ); 345 | } 346 | 347 | // This test covers an edge case non supported by the `chunks` method 348 | // when the slice has only one element. 349 | #[test] 350 | fn chunks_into_iter_edge_case_single_element() { 351 | let v = nev![1]; 352 | let n = NonZeroUsize::new(3).unwrap(); 353 | let c: NEChunks<'_, i32> = v.nonempty_chunks(n); 354 | 355 | let mut iter = c.into_iter(); 356 | 357 | let next = iter.next().unwrap(); 358 | assert_eq!(1, next.len().get()); 359 | assert!(iter.next().is_none()); 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /src/vector.rs: -------------------------------------------------------------------------------- 1 | //! Non-empty Vectors. 2 | 3 | use core::fmt; 4 | use std::cmp::Ordering; 5 | use std::fmt::Debug; 6 | use std::fmt::Formatter; 7 | use std::num::NonZeroUsize; 8 | 9 | #[cfg(feature = "serde")] 10 | use serde::Deserialize; 11 | #[cfg(feature = "serde")] 12 | use serde::Serialize; 13 | 14 | use crate::iter::FromNonEmptyIterator; 15 | use crate::iter::IntoNonEmptyIterator; 16 | use crate::iter::NonEmptyIterator; 17 | use crate::slice::NEChunks; 18 | 19 | /// Like the [`vec!`] macro, but enforces at least one argument. A nice 20 | /// short-hand for constructing [`NEVec`] values. 21 | /// 22 | /// ``` 23 | /// use nonempty_collections::nev; 24 | /// use nonempty_collections::NEVec; 25 | /// 26 | /// let v = nev![1, 2, 3,]; 27 | /// assert_eq!(v.into_iter().collect::>(), vec![1, 2, 3]); 28 | /// 29 | /// let v = nev![1]; 30 | /// assert_eq!(v.into_iter().collect::>(), vec![1]); 31 | /// ``` 32 | /// 33 | /// This won't compile! 34 | /// ``` compile_fail 35 | /// # use nonempty_collections::nev; 36 | /// let v = nev![]; 37 | /// ``` 38 | /// 39 | /// Consider also [`crate::nem!`] and [`crate::nes!`]. 40 | #[macro_export] 41 | macro_rules! nev { 42 | () => {compile_error!("An NEVec cannot be empty")}; 43 | ($h:expr, $( $x:expr ),* $(,)?) => {{ 44 | let mut v = $crate::NEVec::new($h); 45 | $( v.push($x); )* 46 | v 47 | }}; 48 | ($h:expr) => { 49 | $crate::NEVec::new($h) 50 | } 51 | } 52 | 53 | /// A non-empty, growable Vector. 54 | /// 55 | /// The first element can always be accessed in constant time. Similarly, 56 | /// certain functions like [`NEVec::first`] and [`NEVec::last`] always succeed: 57 | /// 58 | /// ``` 59 | /// use nonempty_collections::nev; 60 | /// 61 | /// let s = nev!["Fëanor", "Fingolfin", "Finarfin"]; 62 | /// assert_eq!(&"Fëanor", s.first()); // There is always a first element. 63 | /// assert_eq!(&"Finarfin", s.last()); // There is always a last element. 64 | /// ``` 65 | #[cfg_attr( 66 | feature = "serde", 67 | derive(Deserialize, Serialize), 68 | serde(bound(serialize = "T: Clone + Serialize")), 69 | serde(into = "Vec", try_from = "Vec") 70 | )] 71 | #[allow(clippy::unsafe_derive_deserialize)] // the non-empty invariant is enforced by the deserialize implementation 72 | #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 73 | pub struct NEVec { 74 | inner: Vec, 75 | } 76 | 77 | impl NEVec { 78 | /// Create a new non-empty list with an initial element. 79 | #[must_use] 80 | pub fn new(head: T) -> Self { 81 | NEVec { inner: vec![head] } 82 | } 83 | 84 | /// Creates a new `NEVec` with a single element and specified capacity. 85 | #[must_use] 86 | pub fn with_capacity(capacity: NonZeroUsize, head: T) -> Self { 87 | let mut inner = Vec::with_capacity(capacity.get()); 88 | inner.push(head); 89 | NEVec { inner } 90 | } 91 | 92 | /// Get the first element. Never fails. 93 | #[must_use] 94 | pub fn first(&self) -> &T { 95 | unsafe { self.inner.get_unchecked(0) } 96 | } 97 | 98 | /// Get the mutable reference to the first element. Never fails. 99 | /// 100 | /// # Examples 101 | /// 102 | /// ``` 103 | /// use nonempty_collections::nev; 104 | /// 105 | /// let mut v = nev![42]; 106 | /// let head = v.first_mut(); 107 | /// *head += 1; 108 | /// assert_eq!(v.first(), &43); 109 | /// 110 | /// let mut v = nev![1, 4, 2, 3]; 111 | /// let head = v.first_mut(); 112 | /// *head *= 42; 113 | /// assert_eq!(v.first(), &42); 114 | /// ``` 115 | #[must_use] 116 | pub fn first_mut(&mut self) -> &mut T { 117 | unsafe { self.inner.get_unchecked_mut(0) } 118 | } 119 | 120 | /// Push an element to the end of the list. 121 | pub fn push(&mut self, e: T) { 122 | self.inner.push(e); 123 | } 124 | 125 | /// Pop an element from the end of the list. Is a no-op when [`Self::len()`] 126 | /// is 1. 127 | /// 128 | /// ``` 129 | /// use nonempty_collections::nev; 130 | /// 131 | /// let mut v = nev![1, 2]; 132 | /// assert_eq!(Some(2), v.pop()); 133 | /// assert_eq!(None, v.pop()); 134 | /// ``` 135 | pub fn pop(&mut self) -> Option { 136 | if self.len() > NonZeroUsize::MIN { 137 | self.inner.pop() 138 | } else { 139 | None 140 | } 141 | } 142 | 143 | /// Removes and returns the element at position `index` within the vector, 144 | /// shifting all elements after it to the left. 145 | /// 146 | /// If this [`NEVec`] contains only one element, no removal takes place and 147 | /// `None` will be returned. If there are more elements, the item at the 148 | /// `index` is removed and returned. 149 | /// 150 | /// Note: Because this shifts over the remaining elements, it has a 151 | /// worst-case performance of *O*(*n*). If you don't need the order of 152 | /// elements to be preserved, use [`swap_remove`] instead. 153 | /// 154 | /// [`swap_remove`]: NEVec::swap_remove 155 | /// 156 | /// # Panics 157 | /// 158 | /// Panics if `index` is out of bounds and `self.len() > 1` 159 | /// 160 | /// # Examples 161 | /// 162 | /// ``` 163 | /// use nonempty_collections::nev; 164 | /// 165 | /// let mut v = nev![1, 2, 3]; 166 | /// assert_eq!(v.remove(1), Some(2)); 167 | /// assert_eq!(nev![1, 3], v); 168 | /// ``` 169 | pub fn remove(&mut self, index: usize) -> Option { 170 | (self.len() > NonZeroUsize::MIN).then(|| self.inner.remove(index)) 171 | } 172 | 173 | /// Removes an element from the vector and returns it. 174 | /// 175 | /// If this [`NEVec`] contains only one element, no removal takes place and 176 | /// `None` will be returned. If there are more elements, the item at the 177 | /// `index` is removed and returned. 178 | /// 179 | /// The removed element is replaced by the last element of the vector. 180 | /// 181 | /// This does not preserve ordering of the remaining elements, but is 182 | /// *O*(1). If you need to preserve the element order, use [`remove`] 183 | /// instead. 184 | /// 185 | /// [`remove`]: NEVec::remove 186 | /// 187 | /// # Panics 188 | /// 189 | /// Panics if `index` is out of bounds and `self.len() > 1` 190 | /// 191 | /// # Examples 192 | /// 193 | /// ``` 194 | /// use nonempty_collections::nev; 195 | /// 196 | /// let mut v = nev![1, 2, 3, 4]; 197 | /// assert_eq!(v.swap_remove(1), Some(2)); 198 | /// assert_eq!(nev![1, 4, 3], v); 199 | /// ``` 200 | pub fn swap_remove(&mut self, index: usize) -> Option { 201 | (self.len() > NonZeroUsize::MIN).then(|| self.inner.swap_remove(index)) 202 | } 203 | 204 | /// Retains only the elements specified by the predicate. 205 | /// 206 | /// In other words, remove all elements `e` for which `f(&e)` returns 207 | /// `false`. This method operates in place, visiting each element 208 | /// exactly once in the original order, and preserves the order of the 209 | /// retained elements. 210 | /// 211 | /// If there are one or more items retained `Ok(Self)` is returned with the 212 | /// remaining items. If all items are removed, the inner `Vec` is returned 213 | /// to allowed for reuse of the claimed memory. 214 | /// 215 | /// # Errors 216 | /// Returns `Err` if no elements are retained. 217 | /// 218 | /// # Examples 219 | /// 220 | /// ``` 221 | /// use nonempty_collections::nev; 222 | /// 223 | /// let vec = nev![1, 2, 3, 4]; 224 | /// let vec = vec.retain(|&x| x % 2 == 0); 225 | /// assert_eq!(Ok(nev![2, 4]), vec); 226 | /// ``` 227 | pub fn retain(self, mut f: F) -> Result> 228 | where 229 | F: FnMut(&T) -> bool, 230 | { 231 | self.retain_mut(|item| f(item)) 232 | } 233 | 234 | /// Retains only the elements specified by the predicate, passing a mutable 235 | /// reference to it. 236 | /// 237 | /// In other words, remove all elements `e` such that `f(&mut e)` returns 238 | /// `false`. This method operates in place, visiting each element 239 | /// exactly once in the original order, and preserves the order of the 240 | /// retained elements. 241 | /// 242 | /// If there are one or more items retained `Ok(Self)` is returned with the 243 | /// remaining items. If all items are removed, the inner `Vec` is returned 244 | /// to allowed for reuse of the claimed memory. 245 | /// 246 | /// # Errors 247 | /// Returns `Err` if no elements are retained. 248 | /// 249 | /// # Examples 250 | /// 251 | /// ``` 252 | /// use nonempty_collections::nev; 253 | /// 254 | /// let vec = nev![1, 2, 3, 4]; 255 | /// let vec = vec.retain_mut(|x| { 256 | /// if *x <= 3 { 257 | /// *x += 1; 258 | /// true 259 | /// } else { 260 | /// false 261 | /// } 262 | /// }); 263 | /// assert_eq!(Ok(nev![2, 3, 4]), vec); 264 | /// ``` 265 | pub fn retain_mut(mut self, f: F) -> Result> 266 | where 267 | F: FnMut(&mut T) -> bool, 268 | { 269 | self.inner.retain_mut(f); 270 | if self.inner.is_empty() { 271 | Err(self.inner) 272 | } else { 273 | Ok(self) 274 | } 275 | } 276 | 277 | /// Inserts an element at position index within the vector, shifting all 278 | /// elements after it to the right. 279 | /// 280 | /// # Panics 281 | /// 282 | /// Panics if index > len. 283 | /// 284 | /// # Examples 285 | /// 286 | /// ``` 287 | /// use nonempty_collections::nev; 288 | /// 289 | /// let mut v = nev![1, 2, 3]; 290 | /// v.insert(1, 4); 291 | /// assert_eq!(v, nev![1, 4, 2, 3]); 292 | /// v.insert(4, 5); 293 | /// assert_eq!(v, nev![1, 4, 2, 3, 5]); 294 | /// v.insert(0, 42); 295 | /// assert_eq!(v, nev![42, 1, 4, 2, 3, 5]); 296 | /// ``` 297 | pub fn insert(&mut self, index: usize, element: T) { 298 | self.inner.insert(index, element); 299 | } 300 | 301 | /// Get the length of the list. 302 | #[must_use] 303 | pub fn len(&self) -> NonZeroUsize { 304 | unsafe { NonZeroUsize::new_unchecked(self.inner.len()) } 305 | } 306 | 307 | /// A `NEVec` is never empty. 308 | #[deprecated(since = "0.1.0", note = "A NEVec is never empty.")] 309 | #[must_use] 310 | pub const fn is_empty(&self) -> bool { 311 | false 312 | } 313 | 314 | /// Get the capacity of the list. 315 | #[must_use] 316 | pub fn capacity(&self) -> NonZeroUsize { 317 | unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) } 318 | } 319 | 320 | /// Get the last element. Never fails. 321 | #[must_use] 322 | #[allow(clippy::missing_panics_doc)] // never fails 323 | pub fn last(&self) -> &T { 324 | self.inner.last().unwrap() 325 | } 326 | 327 | /// Get the last element mutably. 328 | #[must_use] 329 | #[allow(clippy::missing_panics_doc)] // never fails 330 | pub fn last_mut(&mut self) -> &mut T { 331 | self.inner.last_mut().unwrap() 332 | } 333 | 334 | /// Check whether an element is contained in the list. 335 | /// 336 | /// ``` 337 | /// use nonempty_collections::nev; 338 | /// 339 | /// let mut l = nev![42, 36, 58]; 340 | /// 341 | /// assert!(l.contains(&42)); 342 | /// assert!(!l.contains(&101)); 343 | /// ``` 344 | #[must_use] 345 | pub fn contains(&self, x: &T) -> bool 346 | where 347 | T: PartialEq, 348 | { 349 | self.inner.contains(x) 350 | } 351 | 352 | /// Get an element by index. 353 | #[must_use] 354 | pub fn get(&self, index: usize) -> Option<&T> { 355 | self.inner.get(index) 356 | } 357 | 358 | /// Get an element by index, mutably. 359 | #[must_use] 360 | pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { 361 | self.inner.get_mut(index) 362 | } 363 | 364 | /// Truncate the list to a certain size. 365 | pub fn truncate(&mut self, len: NonZeroUsize) { 366 | self.inner.truncate(len.get()); 367 | } 368 | 369 | /// Returns a regular iterator over the values in this non-empty vector. 370 | /// 371 | /// For a `NonEmptyIterator` see `Self::nonempty_iter()`. 372 | pub fn iter(&self) -> std::slice::Iter<'_, T> { 373 | self.inner.iter() 374 | } 375 | 376 | /// Returns a regular mutable iterator over the values in this non-empty 377 | /// vector. 378 | /// 379 | /// For a `NonEmptyIterator` see `Self::nonempty_iter_mut()`. 380 | pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { 381 | self.inner.iter_mut() 382 | } 383 | 384 | /// ``` 385 | /// use nonempty_collections::*; 386 | /// 387 | /// let mut l = nev![42, 36, 58]; 388 | /// 389 | /// let mut iter = l.nonempty_iter(); 390 | /// let (first, mut rest_iter) = iter.next(); 391 | /// 392 | /// assert_eq!(first, &42); 393 | /// assert_eq!(rest_iter.next(), Some(&36)); 394 | /// assert_eq!(rest_iter.next(), Some(&58)); 395 | /// assert_eq!(rest_iter.next(), None); 396 | /// ``` 397 | pub fn nonempty_iter(&self) -> Iter<'_, T> { 398 | Iter { 399 | iter: self.inner.iter(), 400 | } 401 | } 402 | 403 | /// Returns an iterator that allows modifying each value. 404 | /// 405 | /// # Examples 406 | /// 407 | /// ``` 408 | /// use nonempty_collections::*; 409 | /// 410 | /// let mut l = nev![42, 36, 58]; 411 | /// 412 | /// for i in l.nonempty_iter_mut() { 413 | /// *i *= 10; 414 | /// } 415 | /// 416 | /// let mut iter = l.nonempty_iter(); 417 | /// let (first, mut rest_iter) = iter.next(); 418 | /// 419 | /// assert_eq!(first, &420); 420 | /// assert_eq!(rest_iter.next(), Some(&360)); 421 | /// assert_eq!(rest_iter.next(), Some(&580)); 422 | /// assert_eq!(rest_iter.next(), None); 423 | /// ``` 424 | pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, T> { 425 | IterMut { 426 | inner: self.inner.iter_mut(), 427 | } 428 | } 429 | 430 | /// Creates a new non-empty vec by cloning the elements from the slice if it 431 | /// is non-empty, returns `None` otherwise. 432 | /// 433 | /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is 434 | /// `NEVec` before proceeding with a computation. Using `try_from_slice` 435 | /// will give us a proof that we have a `NEVec` in the `Some` branch, 436 | /// otherwise it allows the caller to handle the `None` case. 437 | /// 438 | /// # Example use 439 | /// 440 | /// ``` 441 | /// use nonempty_collections::nev; 442 | /// use nonempty_collections::NEVec; 443 | /// 444 | /// let v_vec = NEVec::try_from_slice(&[1, 2, 3, 4, 5]); 445 | /// assert_eq!(v_vec, Some(nev![1, 2, 3, 4, 5])); 446 | /// 447 | /// let empty_vec: Option> = NEVec::try_from_slice(&[]); 448 | /// assert!(empty_vec.is_none()); 449 | /// ``` 450 | #[must_use] 451 | pub fn try_from_slice(slice: &[T]) -> Option> 452 | where 453 | T: Clone, 454 | { 455 | if slice.is_empty() { 456 | None 457 | } else { 458 | Some(NEVec { 459 | inner: slice.to_vec(), 460 | }) 461 | } 462 | } 463 | 464 | /// Often we have a `Vec` (or slice `&[T]`) but want to ensure that it is 465 | /// `NEVec` before proceeding with a computation. Using `try_from_vec` will 466 | /// give us a proof that we have a `NEVec` in the `Some` branch, 467 | /// otherwise it allows the caller to handle the `None` case. 468 | /// 469 | /// This version will consume the `Vec` you pass in. If you would rather 470 | /// pass the data as a slice then use [`NEVec::try_from_slice`]. 471 | /// 472 | /// # Example Use 473 | /// 474 | /// ``` 475 | /// use nonempty_collections::nev; 476 | /// use nonempty_collections::NEVec; 477 | /// 478 | /// let v_vec = NEVec::try_from_vec(vec![1, 2, 3, 4, 5]); 479 | /// assert_eq!(v_vec, Some(nev![1, 2, 3, 4, 5])); 480 | /// 481 | /// let empty_vec: Option> = NEVec::try_from_vec(vec![]); 482 | /// assert!(empty_vec.is_none()); 483 | /// ``` 484 | #[must_use] 485 | pub fn try_from_vec(vec: Vec) -> Option> { 486 | if vec.is_empty() { 487 | None 488 | } else { 489 | Some(NEVec { inner: vec }) 490 | } 491 | } 492 | 493 | /// Deconstruct a `NEVec` into its head and tail. This operation never fails 494 | /// since we are guaranteed to have a head element. 495 | /// 496 | /// # Example Use 497 | /// 498 | /// ``` 499 | /// use nonempty_collections::nev; 500 | /// 501 | /// let mut v = nev![1, 2, 3, 4, 5]; 502 | /// 503 | /// // Guaranteed to have the head and we also get the tail. 504 | /// assert_eq!(v.split_first(), (&1, &[2, 3, 4, 5][..])); 505 | /// 506 | /// let v = nev![1]; 507 | /// 508 | /// // Guaranteed to have the head element. 509 | /// assert_eq!(v.split_first(), (&1, &[][..])); 510 | /// ``` 511 | #[must_use] 512 | #[allow(clippy::missing_panics_doc)] // never fails 513 | pub fn split_first(&self) -> (&T, &[T]) { 514 | self.inner.split_first().unwrap() 515 | } 516 | 517 | /// Deconstruct a `NEVec` into its first, last, and 518 | /// middle elements, in that order. 519 | /// 520 | /// If there is only one element then first == last. 521 | /// 522 | /// # Example Use 523 | /// 524 | /// ``` 525 | /// use nonempty_collections::nev; 526 | /// 527 | /// let mut v = nev![1, 2, 3, 4, 5]; 528 | /// 529 | /// // Guaranteed to have the last element and the elements 530 | /// // preceding it. 531 | /// assert_eq!(v.split(), (&1, &[2, 3, 4][..], &5)); 532 | /// 533 | /// let v = nev![1]; 534 | /// 535 | /// // Guaranteed to have the last element. 536 | /// assert_eq!(v.split(), (&1, &[][..], &1)); 537 | /// ``` 538 | #[must_use] 539 | pub fn split(&self) -> (&T, &[T], &T) { 540 | let (first, rest) = self.split_first(); 541 | if let Some((last, middle)) = rest.split_last() { 542 | (first, middle, last) 543 | } else { 544 | (first, &[], first) 545 | } 546 | } 547 | 548 | /// Append a `Vec` to the tail of the `NEVec`. 549 | /// 550 | /// # Example Use 551 | /// 552 | /// ``` 553 | /// use nonempty_collections::nev; 554 | /// 555 | /// let mut v = nev![1]; 556 | /// let mut vec = vec![2, 3, 4, 5]; 557 | /// v.append(&mut vec); 558 | /// 559 | /// let mut expected = nev![1, 2, 3, 4, 5]; 560 | /// assert_eq!(v, expected); 561 | /// ``` 562 | pub fn append(&mut self, other: &mut Vec) { 563 | self.inner.append(other); 564 | } 565 | 566 | /// Binary searches this sorted non-empty vector for a given element. 567 | /// 568 | /// If the value is found then `Result::Ok` is returned, containing the 569 | /// index of the matching element. If there are multiple matches, then any 570 | /// one of the matches could be returned. 571 | /// 572 | /// # Errors 573 | /// 574 | /// If the value is not found then `Result::Err` is returned, containing the 575 | /// index where a matching element could be inserted while maintaining 576 | /// sorted order. 577 | /// 578 | /// # Examples 579 | /// 580 | /// ``` 581 | /// use nonempty_collections::nev; 582 | /// 583 | /// let v = nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; 584 | /// assert_eq!(v.binary_search(&0), Ok(0)); 585 | /// assert_eq!(v.binary_search(&13), Ok(9)); 586 | /// assert_eq!(v.binary_search(&4), Err(7)); 587 | /// assert_eq!(v.binary_search(&100), Err(13)); 588 | /// let r = v.binary_search(&1); 589 | /// assert!(match r { 590 | /// Ok(1..=4) => true, 591 | /// _ => false, 592 | /// }); 593 | /// ``` 594 | /// 595 | /// If you want to insert an item to a sorted non-empty vector, while 596 | /// maintaining sort order: 597 | /// 598 | /// ``` 599 | /// use nonempty_collections::nev; 600 | /// 601 | /// let mut v = nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; 602 | /// let num = 42; 603 | /// let idx = v.binary_search(&num).unwrap_or_else(|x| x); 604 | /// v.insert(idx, num); 605 | /// assert_eq!(v, nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); 606 | /// ``` 607 | pub fn binary_search(&self, x: &T) -> Result 608 | where 609 | T: Ord, 610 | { 611 | self.binary_search_by(|p| p.cmp(x)) 612 | } 613 | 614 | /// Binary searches this sorted non-empty with a comparator function. 615 | /// 616 | /// The comparator function should implement an order consistent with the 617 | /// sort order of the underlying slice, returning an order code that 618 | /// indicates whether its argument is Less, Equal or Greater the desired 619 | /// target. 620 | /// 621 | /// If the value is found then `Result::Ok` is returned, containing the 622 | /// index of the matching element. If there are multiple matches, then any 623 | /// one of the matches could be returned. 624 | /// 625 | /// # Errors 626 | /// If the value is not found then `Result::Err` is returned, containing the 627 | /// index where a matching element could be inserted while maintaining 628 | /// sorted order. 629 | /// 630 | /// # Examples 631 | /// 632 | /// Looks up a series of four elements. The first is found, with a uniquely 633 | /// determined position; the second and third are not found; the fourth 634 | /// could match any position from 1 to 4. 635 | /// 636 | /// ``` 637 | /// use nonempty_collections::nev; 638 | /// 639 | /// let v = nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; 640 | /// let seek = 0; 641 | /// assert_eq!(v.binary_search_by(|probe| probe.cmp(&seek)), Ok(0)); 642 | /// let seek = 13; 643 | /// assert_eq!(v.binary_search_by(|probe| probe.cmp(&seek)), Ok(9)); 644 | /// let seek = 4; 645 | /// assert_eq!(v.binary_search_by(|probe| probe.cmp(&seek)), Err(7)); 646 | /// let seek = 100; 647 | /// assert_eq!(v.binary_search_by(|probe| probe.cmp(&seek)), Err(13)); 648 | /// let seek = 1; 649 | /// let r = v.binary_search_by(|probe| probe.cmp(&seek)); 650 | /// assert!(match r { 651 | /// Ok(1..=4) => true, 652 | /// _ => false, 653 | /// }); 654 | /// ``` 655 | pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result 656 | where 657 | F: FnMut(&'a T) -> Ordering, 658 | { 659 | self.inner.binary_search_by(f) 660 | } 661 | 662 | /// Binary searches this sorted non-empty vector with a key extraction 663 | /// function. 664 | /// 665 | /// Assumes that the vector is sorted by the key. 666 | /// 667 | /// If the value is found then `Result::Ok` is returned, containing the 668 | /// index of the matching element. If there are multiple matches, then any 669 | /// one of the matches could be returned. 670 | /// 671 | /// # Errors 672 | /// If the value is not found then `Result::Err` is returned, containing the 673 | /// index where a matching element could be inserted while maintaining 674 | /// sorted order. 675 | /// 676 | /// # Examples 677 | /// 678 | /// Looks up a series of four elements in a non-empty vector of pairs sorted 679 | /// by their second elements. The first is found, with a uniquely determined 680 | /// position; the second and third are not found; the fourth could match any 681 | /// position in [1, 4]. 682 | /// 683 | /// ``` 684 | /// use nonempty_collections::nev; 685 | /// 686 | /// let v = nev![ 687 | /// (0, 0), 688 | /// (2, 1), 689 | /// (4, 1), 690 | /// (5, 1), 691 | /// (3, 1), 692 | /// (1, 2), 693 | /// (2, 3), 694 | /// (4, 5), 695 | /// (5, 8), 696 | /// (3, 13), 697 | /// (1, 21), 698 | /// (2, 34), 699 | /// (4, 55) 700 | /// ]; 701 | /// 702 | /// assert_eq!(v.binary_search_by_key(&0, |&(a, b)| b), Ok(0)); 703 | /// assert_eq!(v.binary_search_by_key(&13, |&(a, b)| b), Ok(9)); 704 | /// assert_eq!(v.binary_search_by_key(&4, |&(a, b)| b), Err(7)); 705 | /// assert_eq!(v.binary_search_by_key(&100, |&(a, b)| b), Err(13)); 706 | /// let r = v.binary_search_by_key(&1, |&(a, b)| b); 707 | /// assert!(match r { 708 | /// Ok(1..=4) => true, 709 | /// _ => false, 710 | /// }); 711 | /// ``` 712 | pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result 713 | where 714 | B: Ord, 715 | F: FnMut(&'a T) -> B, 716 | { 717 | self.binary_search_by(|k| f(k).cmp(b)) 718 | } 719 | 720 | /// Sorts the `NEVec` in place. 721 | /// 722 | /// See also [`slice::sort`]. 723 | /// 724 | /// # Examples 725 | /// 726 | /// ``` 727 | /// use nonempty_collections::nev; 728 | /// 729 | /// let mut n = nev![5, 4, 3, 2, 1]; 730 | /// n.sort(); 731 | /// assert_eq!(nev![1, 2, 3, 4, 5], n); 732 | /// 733 | /// // Naturally, sorting a sorted result should remain the same. 734 | /// n.sort(); 735 | /// assert_eq!(nev![1, 2, 3, 4, 5], n); 736 | /// ``` 737 | pub fn sort(&mut self) 738 | where 739 | T: Ord, 740 | { 741 | self.inner.sort(); 742 | } 743 | 744 | /// Like [`NEVec::sort`], but sorts the `NEVec` with a given comparison 745 | /// function. 746 | /// 747 | /// See also [`slice::sort_by`]. 748 | /// 749 | /// ``` 750 | /// use nonempty_collections::nev; 751 | /// 752 | /// let mut n = nev!["Sirion", "Gelion", "Narog"]; 753 | /// n.sort_by(|a, b| b.cmp(&a)); 754 | /// assert_eq!(nev!["Sirion", "Narog", "Gelion"], n); 755 | /// ``` 756 | pub fn sort_by(&mut self, f: F) 757 | where 758 | F: FnMut(&T, &T) -> Ordering, 759 | { 760 | self.inner.sort_by(f); 761 | } 762 | 763 | /// Like [`NEVec::sort`], but sorts the `NEVec` after first transforming 764 | /// each element into something easily comparable. Beware of expensive key 765 | /// functions, as the results of each call are not cached. 766 | /// 767 | /// See also [`slice::sort_by_key`]. 768 | /// 769 | /// ``` 770 | /// use nonempty_collections::nev; 771 | /// 772 | /// let mut n = nev![-5, 4, -3, 2, 1]; 773 | /// n.sort_by_key(|x| x * x); 774 | /// assert_eq!(nev![1, 2, -3, 4, -5], n); 775 | /// 776 | /// // Naturally, sorting a sorted result should remain the same. 777 | /// n.sort_by_key(|x| x * x); 778 | /// assert_eq!(nev![1, 2, -3, 4, -5], n); 779 | /// ``` 780 | pub fn sort_by_key(&mut self, f: F) 781 | where 782 | F: FnMut(&T) -> K, 783 | K: Ord, 784 | { 785 | self.inner.sort_by_key(f); 786 | } 787 | 788 | /// Yields a `NESlice`. 789 | #[must_use] 790 | pub fn as_nonempty_slice(&self) -> crate::NESlice<'_, T> { 791 | crate::NESlice::from_slice_unchecked(self.inner.as_slice()) 792 | } 793 | 794 | /// Removes all but the first of consecutive elements in the vector that 795 | /// resolve to the same key. 796 | /// 797 | /// If the vector is sorted, this removes all duplicates. 798 | /// 799 | /// # Examples 800 | /// 801 | /// ``` 802 | /// use nonempty_collections::nev; 803 | /// let mut v = nev![10, 20, 21, 30, 20]; 804 | /// 805 | /// v.dedup_by_key(|i| *i / 10); 806 | /// 807 | /// assert_eq!(nev![10, 20, 30, 20], v); 808 | /// ``` 809 | pub fn dedup_by_key(&mut self, mut key: F) 810 | where 811 | F: FnMut(&mut T) -> K, 812 | K: PartialEq, 813 | { 814 | self.dedup_by(|a, b| key(a) == key(b)); 815 | } 816 | 817 | /// Removes all but the first of consecutive elements in the vector 818 | /// satisfying a given equality relation. 819 | /// 820 | /// The `same_bucket` function is passed references to two elements from the 821 | /// vector and must determine if the elements compare equal. The 822 | /// elements are passed in opposite order from their order in the slice, 823 | /// so if `same_bucket(a, b)` returns `true`, `a` is removed. 824 | /// 825 | /// If the vector is sorted, this removes all duplicates. 826 | /// 827 | /// # Examples 828 | /// 829 | /// ``` 830 | /// use nonempty_collections::nev; 831 | /// let mut v = nev!["foo", "Foo", "foo", "bar", "Bar", "baz", "bar"]; 832 | /// 833 | /// v.dedup_by(|a, b| a.eq_ignore_ascii_case(b)); 834 | /// 835 | /// assert_eq!(nev!["foo", "bar", "baz", "bar"], v); 836 | /// ``` 837 | pub fn dedup_by(&mut self, same_bucket: F) 838 | where 839 | F: FnMut(&mut T, &mut T) -> bool, 840 | { 841 | self.inner.dedup_by(same_bucket); 842 | } 843 | 844 | /// Returns a non-empty iterator over `chunk_size` elements of the `NEVec` 845 | /// at a time, starting at the beginning of the `NEVec`. 846 | /// 847 | /// ``` 848 | /// use std::num::NonZeroUsize; 849 | /// 850 | /// use nonempty_collections::*; 851 | /// 852 | /// let v = nev![1, 2, 3, 4, 5, 6]; 853 | /// let n = NonZeroUsize::new(2).unwrap(); 854 | /// let r = v.nonempty_chunks(n).collect::>(); 855 | /// 856 | /// let a = nev![1, 2]; 857 | /// let b = nev![3, 4]; 858 | /// let c = nev![5, 6]; 859 | /// 860 | /// assert_eq!( 861 | /// r, 862 | /// nev![ 863 | /// a.as_nonempty_slice(), 864 | /// b.as_nonempty_slice(), 865 | /// c.as_nonempty_slice() 866 | /// ] 867 | /// ); 868 | /// ``` 869 | pub fn nonempty_chunks(&self, chunk_size: NonZeroUsize) -> NEChunks<'_, T> { 870 | NEChunks { 871 | inner: self.inner.chunks(chunk_size.get()), 872 | } 873 | } 874 | 875 | /// Returns the index of the partition point according to the given 876 | /// predicate (the index of the first element of the second partition). 877 | /// 878 | /// The vector is assumed to be partitioned according to the given 879 | /// predicate. This means that all elements for which the predicate 880 | /// returns true are at the start of the vector and all elements for 881 | /// which the predicate returns false are at the end. For example, `[7, 882 | /// 15, 3, 5, 4, 12, 6]` is partitioned under the predicate `x % 2 != 0` 883 | /// (all odd numbers are at the start, all even at the end). 884 | /// 885 | /// If this vector is not partitioned, the returned result is unspecified 886 | /// and meaningless, as this method performs a kind of binary search. 887 | /// 888 | /// See also [`NEVec::binary_search`], [`NEVec::binary_search_by`], and 889 | /// [`NEVec::binary_search_by_key`]. 890 | /// 891 | /// # Examples 892 | /// 893 | /// ``` 894 | /// # use nonempty_collections::*; 895 | /// # 896 | /// let v = nev![1, 2, 3, 3, 5, 6, 7]; 897 | /// let i = v.partition_point(|&x| x < 5); 898 | /// 899 | /// assert_eq!(i, 4); 900 | /// ``` 901 | /// 902 | /// If all elements of the non-empty vector match the predicate, then the 903 | /// length of the vector will be returned: 904 | /// 905 | /// ``` 906 | /// # use nonempty_collections::*; 907 | /// # 908 | /// let a = nev![2, 4, 8]; 909 | /// assert_eq!(a.partition_point(|&x| x < 100), a.len().get()); 910 | /// ``` 911 | /// 912 | /// If you want to insert an item to a sorted vector, while maintaining 913 | /// sort order: 914 | /// 915 | /// ``` 916 | /// # use nonempty_collections::*; 917 | /// # 918 | /// let mut s = nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; 919 | /// let num = 42; 920 | /// let idx = s.partition_point(|&x| x < num); 921 | /// s.insert(idx, num); 922 | /// assert_eq!(s, nev![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); 923 | /// ``` 924 | #[must_use] 925 | pub fn partition_point

(&self, mut pred: P) -> usize 926 | where 927 | P: FnMut(&T) -> bool, 928 | { 929 | self.binary_search_by(|x| { 930 | if pred(x) { 931 | Ordering::Less 932 | } else { 933 | Ordering::Greater 934 | } 935 | }) 936 | .unwrap_or_else(|i| i) 937 | } 938 | } 939 | 940 | impl NEVec { 941 | /// Removes consecutive repeated elements in the vector according to the 942 | /// [`PartialEq`] trait implementation. 943 | /// 944 | /// If the vector is sorted, this removes all duplicates. 945 | /// 946 | /// # Examples 947 | /// 948 | /// ``` 949 | /// use nonempty_collections::nev; 950 | /// let mut v = nev![1, 1, 1, 2, 3, 2, 2, 1]; 951 | /// v.dedup(); 952 | /// assert_eq!(nev![1, 2, 3, 2, 1], v); 953 | /// ``` 954 | pub fn dedup(&mut self) { 955 | self.dedup_by(|a, b| a == b); 956 | } 957 | } 958 | 959 | impl From> for Vec { 960 | /// Turns a non-empty list into a `Vec`. 961 | fn from(nonempty: NEVec) -> Vec { 962 | nonempty.inner 963 | } 964 | } 965 | 966 | impl From<(T, Vec)> for NEVec { 967 | /// Turns a pair of an element and a `Vec` into 968 | /// a `NEVec`. 969 | fn from((head, tail): (T, Vec)) -> Self { 970 | let mut vec = vec![head]; 971 | vec.extend(tail); 972 | NEVec { inner: vec } 973 | } 974 | } 975 | 976 | /// ``` 977 | /// use nonempty_collections::*; 978 | /// 979 | /// let v0 = nev![1, 2, 3]; 980 | /// let v1: NEVec<_> = v0.nonempty_iter().cloned().collect(); 981 | /// assert_eq!(v0, v1); 982 | /// ``` 983 | impl FromNonEmptyIterator for NEVec { 984 | fn from_nonempty_iter(iter: I) -> Self 985 | where 986 | I: IntoNonEmptyIterator, 987 | { 988 | NEVec { 989 | inner: iter.into_nonempty_iter().into_iter().collect(), 990 | } 991 | } 992 | } 993 | 994 | /// A non-empty iterator over the values of an [`NEVec`]. 995 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 996 | pub struct Iter<'a, T: 'a> { 997 | iter: std::slice::Iter<'a, T>, 998 | } 999 | 1000 | impl NonEmptyIterator for Iter<'_, T> {} 1001 | 1002 | impl<'a, T> IntoIterator for Iter<'a, T> { 1003 | type Item = &'a T; 1004 | 1005 | type IntoIter = std::slice::Iter<'a, T>; 1006 | 1007 | fn into_iter(self) -> Self::IntoIter { 1008 | self.iter 1009 | } 1010 | } 1011 | 1012 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` (see https://github.com/rust-lang/rust/issues/26925 for more info) 1013 | impl Clone for Iter<'_, T> { 1014 | fn clone(&self) -> Self { 1015 | Iter { 1016 | iter: self.iter.clone(), 1017 | } 1018 | } 1019 | } 1020 | 1021 | impl Debug for Iter<'_, T> { 1022 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1023 | self.iter.fmt(f) 1024 | } 1025 | } 1026 | 1027 | /// A non-empty iterator over mutable values from an [`NEVec`]. 1028 | #[derive(Debug)] 1029 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1030 | pub struct IterMut<'a, T: 'a> { 1031 | inner: std::slice::IterMut<'a, T>, 1032 | } 1033 | 1034 | impl NonEmptyIterator for IterMut<'_, T> {} 1035 | 1036 | impl<'a, T> IntoIterator for IterMut<'a, T> { 1037 | type Item = &'a mut T; 1038 | 1039 | type IntoIter = std::slice::IterMut<'a, T>; 1040 | 1041 | fn into_iter(self) -> Self::IntoIter { 1042 | self.inner 1043 | } 1044 | } 1045 | 1046 | /// An owned non-empty iterator over values from an [`NEVec`]. 1047 | #[derive(Clone)] 1048 | #[must_use = "non-empty iterators are lazy and do nothing unless consumed"] 1049 | pub struct IntoIter { 1050 | inner: std::vec::IntoIter, 1051 | } 1052 | 1053 | impl NonEmptyIterator for IntoIter {} 1054 | 1055 | impl IntoIterator for IntoIter { 1056 | type Item = T; 1057 | 1058 | type IntoIter = std::vec::IntoIter; 1059 | 1060 | fn into_iter(self) -> Self::IntoIter { 1061 | self.inner 1062 | } 1063 | } 1064 | 1065 | impl Debug for IntoIter { 1066 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1067 | self.inner.fmt(f) 1068 | } 1069 | } 1070 | 1071 | impl IntoNonEmptyIterator for NEVec { 1072 | type IntoNEIter = IntoIter; 1073 | 1074 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 1075 | IntoIter { 1076 | inner: self.inner.into_iter(), 1077 | } 1078 | } 1079 | } 1080 | 1081 | impl<'a, T> IntoNonEmptyIterator for &'a NEVec { 1082 | type IntoNEIter = Iter<'a, T>; 1083 | 1084 | fn into_nonempty_iter(self) -> Self::IntoNEIter { 1085 | self.nonempty_iter() 1086 | } 1087 | } 1088 | 1089 | impl IntoIterator for NEVec { 1090 | type Item = T; 1091 | type IntoIter = std::vec::IntoIter; 1092 | 1093 | fn into_iter(self) -> Self::IntoIter { 1094 | self.inner.into_iter() 1095 | } 1096 | } 1097 | 1098 | impl<'a, T> IntoIterator for &'a NEVec { 1099 | type Item = &'a T; 1100 | type IntoIter = std::slice::Iter<'a, T>; 1101 | 1102 | fn into_iter(self) -> Self::IntoIter { 1103 | self.iter() 1104 | } 1105 | } 1106 | 1107 | impl<'a, T> IntoIterator for &'a mut NEVec { 1108 | type Item = &'a mut T; 1109 | type IntoIter = std::slice::IterMut<'a, T>; 1110 | 1111 | fn into_iter(self) -> Self::IntoIter { 1112 | self.iter_mut() 1113 | } 1114 | } 1115 | 1116 | impl std::ops::Index for NEVec { 1117 | type Output = T; 1118 | 1119 | /// ``` 1120 | /// use nonempty_collections::nev; 1121 | /// 1122 | /// let v = nev![1, 2, 3, 4, 5]; 1123 | /// 1124 | /// assert_eq!(v[0], 1); 1125 | /// assert_eq!(v[1], 2); 1126 | /// assert_eq!(v[3], 4); 1127 | /// ``` 1128 | fn index(&self, index: usize) -> &T { 1129 | self.inner.index(index) 1130 | } 1131 | } 1132 | 1133 | impl std::ops::IndexMut for NEVec { 1134 | fn index_mut(&mut self, index: usize) -> &mut T { 1135 | self.inner.index_mut(index) 1136 | } 1137 | } 1138 | 1139 | impl Debug for NEVec { 1140 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1141 | self.inner.fmt(f) 1142 | } 1143 | } 1144 | 1145 | impl TryFrom> for NEVec { 1146 | type Error = crate::Error; 1147 | 1148 | fn try_from(vec: Vec) -> Result { 1149 | NEVec::try_from_vec(vec).ok_or(crate::Error::Empty) 1150 | } 1151 | } 1152 | 1153 | impl Extend for NEVec { 1154 | fn extend(&mut self, iter: I) 1155 | where 1156 | I: IntoIterator, 1157 | { 1158 | self.inner.extend(iter); 1159 | } 1160 | } 1161 | 1162 | #[cfg(test)] 1163 | mod tests { 1164 | use crate::nev; 1165 | use crate::NEVec; 1166 | 1167 | struct Foo { 1168 | user: String, 1169 | } 1170 | 1171 | #[test] 1172 | fn macro_usage() { 1173 | let a = Foo { 1174 | user: "a".to_string(), 1175 | }; 1176 | let b = Foo { 1177 | user: "b".to_string(), 1178 | }; 1179 | 1180 | let v = nev![a, b]; 1181 | assert_eq!("a", v.first().user); 1182 | } 1183 | 1184 | #[test] 1185 | fn test_from_conversion() { 1186 | let result = NEVec::from((1, vec![2, 3, 4, 5])); 1187 | let expected = NEVec { 1188 | inner: vec![1, 2, 3, 4, 5], 1189 | }; 1190 | assert_eq!(result, expected); 1191 | } 1192 | 1193 | #[test] 1194 | fn test_into_iter() { 1195 | let nonempty = NEVec::from((0usize, vec![1, 2, 3])); 1196 | for (i, n) in nonempty.into_iter().enumerate() { 1197 | assert_eq!(i, n); 1198 | } 1199 | } 1200 | 1201 | #[test] 1202 | fn test_iter_syntax() { 1203 | let nonempty = NEVec::from((0, vec![1, 2, 3])); 1204 | for n in &nonempty { 1205 | assert_eq!(*n, *n); // Prove that we're dealing with references. 1206 | } 1207 | for _ in nonempty {} 1208 | } 1209 | 1210 | #[cfg(feature = "serde")] 1211 | mod serialize { 1212 | use serde::Deserialize; 1213 | use serde::Serialize; 1214 | 1215 | use crate::NEVec; 1216 | 1217 | #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] 1218 | struct SimpleSerializable(i32); 1219 | 1220 | #[test] 1221 | fn test_simple_round_trip() -> Result<(), Box> { 1222 | // Given 1223 | let mut v = NEVec::new(SimpleSerializable(42)); 1224 | v.push(SimpleSerializable(777)); 1225 | let expected_value = v.clone(); 1226 | 1227 | // When 1228 | let res = 1229 | serde_json::from_str::<'_, NEVec>(&serde_json::to_string(&v)?)?; 1230 | 1231 | // Then 1232 | assert_eq!(res, expected_value); 1233 | 1234 | Ok(()) 1235 | } 1236 | } 1237 | 1238 | #[test] 1239 | fn test_result_collect() { 1240 | use crate::IntoNonEmptyIterator; 1241 | use crate::NonEmptyIterator; 1242 | 1243 | let nonempty = nev![2, 4, 8]; 1244 | let output = nonempty 1245 | .into_nonempty_iter() 1246 | .map(|n| { 1247 | if n % 2 == 0 { 1248 | Ok(n) 1249 | } else { 1250 | Err("odd number!") 1251 | } 1252 | }) 1253 | .collect::, &'static str>>(); 1254 | 1255 | assert_eq!(output, Ok(nev![2, 4, 8])); 1256 | 1257 | let nonempty = nev![2, 1, 8]; 1258 | let output = nonempty 1259 | .into_nonempty_iter() 1260 | .map(|n| { 1261 | if n % 2 == 0 { 1262 | Ok(n) 1263 | } else { 1264 | Err("odd number!") 1265 | } 1266 | }) 1267 | .collect::, &'static str>>(); 1268 | 1269 | assert_eq!(output, Err("odd number!")); 1270 | } 1271 | 1272 | #[test] 1273 | fn test_as_slice() { 1274 | let nonempty = NEVec::from((0, vec![1, 2, 3])); 1275 | assert_eq!( 1276 | crate::NESlice::try_from_slice(&[0, 1, 2, 3]).unwrap(), 1277 | nonempty.as_nonempty_slice(), 1278 | ); 1279 | } 1280 | 1281 | #[test] 1282 | fn debug_impl() { 1283 | let actual = format!("{:?}", nev![0, 1, 2, 3]); 1284 | let expected = format!("{:?}", vec![0, 1, 2, 3]); 1285 | assert_eq!(expected, actual); 1286 | } 1287 | 1288 | #[test] 1289 | fn sorting() { 1290 | let mut n = nev![1, 5, 4, 3, 2, 1]; 1291 | n.sort(); 1292 | assert_eq!(nev![1, 1, 2, 3, 4, 5], n); 1293 | 1294 | let mut m = nev![1]; 1295 | m.sort(); 1296 | assert_eq!(nev![1], m); 1297 | } 1298 | 1299 | #[test] 1300 | fn extend() { 1301 | let mut n = nev![1, 2, 3]; 1302 | let v = vec![4, 5, 6]; 1303 | n.extend(v); 1304 | 1305 | assert_eq!(n, nev![1, 2, 3, 4, 5, 6]); 1306 | } 1307 | 1308 | #[test] 1309 | fn iter_mut() { 1310 | let mut v = nev![0, 1, 2, 3]; 1311 | 1312 | v.iter_mut().for_each(|x| { 1313 | *x += 1; 1314 | }); 1315 | 1316 | assert_eq!(nev![1, 2, 3, 4], v); 1317 | 1318 | for x in &mut v { 1319 | *x -= 1; 1320 | } 1321 | assert_eq!(nev![0, 1, 2, 3], v); 1322 | } 1323 | 1324 | #[test] 1325 | fn retain() { 1326 | // retain all 1327 | let v = nev![0, 1, 2, 3]; 1328 | let result = v.retain(|_| true); 1329 | assert_eq!( 1330 | Ok(nev![0, 1, 2, 3]), 1331 | result, 1332 | "retaining all values should not change anything" 1333 | ); 1334 | // retain none 1335 | let v = nev![0, 1, 2, 3]; 1336 | let result = v.retain(|_| false); 1337 | assert_eq!( 1338 | Err(vec![]), 1339 | result, 1340 | "removing all values should return a regular vec" 1341 | ); 1342 | // retain one 1343 | let v = nev![3, 7]; 1344 | let result = v.retain_mut(|x| *x == 3); 1345 | assert_eq!(Ok(nev![3]), result, "only 3 should remain"); 1346 | } 1347 | 1348 | #[test] 1349 | fn retain_mut() { 1350 | // retain all 1351 | let v = nev![0, 1, 2, 3]; 1352 | let result = v.retain_mut(|x| { 1353 | *x += 1; 1354 | true 1355 | }); 1356 | assert_eq!( 1357 | Ok(nev![1, 2, 3, 4]), 1358 | result, 1359 | "each value must be incremented by 1" 1360 | ); 1361 | let v = nev![0, 1, 2, 3]; 1362 | // retain none 1363 | let result = v.retain_mut(|x| { 1364 | *x += 1; 1365 | false 1366 | }); 1367 | assert_eq!( 1368 | Err(vec![]), 1369 | result, 1370 | "removing all values should return a regular vec" 1371 | ); 1372 | // retain one 1373 | let v = nev![3, 7]; 1374 | let result = v.retain_mut(|x| { 1375 | if *x == 3 { 1376 | *x += 1; 1377 | true 1378 | } else { 1379 | false 1380 | } 1381 | }); 1382 | assert_eq!(Ok(nev![4]), result, "only 3+1 = 4 should remain"); 1383 | } 1384 | } 1385 | --------------------------------------------------------------------------------