From 3c506ce99efe7ba37370491861e30bcbd1d9b0c8 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Sat, 19 Jul 2025 13:50:33 +0100 Subject: [PATCH 1/6] feat: update bincode optional feature It was a misnomer to name the feature flag `bincode2` since that is the name of unmaintained library. The library `bincode` is actively maintained, so the feature flag is named after it instead. There is a proper version release v2.0.1 now, which is specified instead. The derive is cleaned up, and there is a roundtrip test added. --- Cargo.toml | 4 ++-- src/lib.rs | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c6ad4c..08aa784 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,14 @@ repository = "https://github.com/cloudhead/nonempty" [dependencies] serde = { features = ["derive", "alloc"], default-features = false, optional = true, version = "1" } arbitrary = { features = ["derive"], optional = true, version = "1" } -bincode = { optional = true, version = "2.0.0-rc.3" } +bincode = { optional = true, version = "2.0.1" } [features] default = ["std"] std = [] serialize = ["dep:serde"] arbitrary = ["dep:arbitrary"] -bincode2 = ["dep:bincode"] +bincode = ["dep:bincode"] [dev-dependencies] serde_json = "1" diff --git a/src/lib.rs b/src/lib.rs index 15815b0..0fa9485 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,10 +80,10 @@ //! //! * `serialize`: `serde` support. //! * `arbitrary`: `arbitrary` support. -//! * `bincode2`" `bincode@2.0.0-rc.3` support. +//! * `bincode`" `bincode` support. #[cfg(feature = "arbitrary")] use arbitrary::Arbitrary; -#[cfg(feature = "bincode2")] +#[cfg(feature = "bincode")] use bincode::{Decode, Encode}; #[cfg(feature = "serialize")] use serde::{ @@ -142,15 +142,8 @@ macro_rules! nonempty { /// Non-empty vector. #[cfg_attr(feature = "serialize", derive(Deserialize))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(feature = "bincode2", derive(Encode, Decode))] #[cfg_attr(feature = "serialize", serde(try_from = "Vec"))] -#[cfg_attr( - feature = "bincode2", - bincode( - encode_bounds = "T: Encode + 'static", - decode_bounds = "T: Decode + 'static", - ) -)] +#[cfg_attr(feature = "bincode", derive(Encode, Decode))] #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct NonEmpty { pub head: T, @@ -1264,6 +1257,34 @@ mod tests { } } + #[cfg(feature = "bincode")] + mod bincode { + use crate::NonEmpty; + use alloc::boxed::Box; + + #[derive(Clone, Debug, Eq, PartialEq, bincode::Encode, bincode::Decode)] + pub struct SimpleSerializable(pub i32); + + #[test] + fn test_simple_round_trip() -> Result<(), Box> { + // Given + let mut non_empty = NonEmpty::new(SimpleSerializable(42)); + non_empty.push(SimpleSerializable(777)); + + // When + let config = bincode::config::standard(); + let (res, _) = bincode::decode_from_slice::, _>( + &bincode::encode_to_vec(non_empty.clone(), config)?, + config, + )?; + + // Then + assert_eq!(res, non_empty); + + Ok(()) + } + } + #[cfg(feature = "arbitrary")] mod arbitrary { use crate::NonEmpty; From 29d84e296ca10c878139b2a65118abcfb94408fa Mon Sep 17 00:00:00 2001 From: Serhii Potapov Date: Sun, 22 Dec 2024 18:54:07 +0100 Subject: [PATCH 2/6] fix: use vec! in nonempty! As pointed out[^0], `nonempty!` runs into macro hygiene issues. Use the same approach as tracing[^1] to re-export the `vec!` macro and qualify it using the `$crate` syntax. [^0]: https://github.com/cloudhead/nonempty/pull/70#discussion_r2008824990 [^1]: https://github.com/tokio-rs/tracing/blob/e63ef57f3d686abe3727ddd586eb9af73d6715b7/tracing/src/lib.rs#L987 --- src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0fa9485..4bbf6c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,6 +104,11 @@ use alloc::vec::{self, Vec}; pub mod nonzero; +#[doc(hidden)] +pub mod __macro_support { + pub use alloc::vec; +} + /// Like the `vec!` macro, but enforces at least one argument. A nice short-hand /// for constructing [`NonEmpty`] values. /// @@ -128,13 +133,13 @@ pub mod nonzero; #[macro_export] macro_rules! nonempty { ($h:expr, $( $x:expr ),* $(,)?) => {{ - let tail = vec![$($x),*]; + let tail = $crate::__macro_support::vec![$($x),*]; $crate::NonEmpty { head: $h, tail } }}; ($h:expr) => { $crate::NonEmpty { head: $h, - tail: alloc::vec::Vec::new(), + tail: $crate::__macro_support::vec![], } }; } From 5442b77445bb017610e3773209ac362f6159f0ca Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Sat, 19 Jul 2025 14:55:51 +0100 Subject: [PATCH 3/6] chore: link `FromIterator` and `Iterator` docs --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4bbf6c3..b70111a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,8 +71,8 @@ //! # Caveats //! //! Since `NonEmpty` must have a least one element, it is not possible to -//! implement the `FromIterator` trait for it. We can't know, in general, if -//! any given `Iterator` actually contains something. +//! implement the [`FromIterator`] trait for it. We can't know, in general, if +//! any given [`Iterator`] actually contains something. #![no_std] From ef60de1577f56e8de69386fe1166a43aefafc157 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Sat, 19 Jul 2025 14:58:03 +0100 Subject: [PATCH 4/6] fix: NonEmpty::capacity returns NonZeroUsize --- CHANGELOG.md | 3 +++ src/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 673fb8b..7a3ea39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this library adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.12.0 +- `NonEmpty::capacity` returns `NonZeroUsize` + ## 0.11.0 ### Added diff --git a/src/lib.rs b/src/lib.rs index b70111a..07465bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -349,8 +349,8 @@ impl NonEmpty { } /// Get the capacity of the list. - pub fn capacity(&self) -> usize { - self.tail.capacity() + 1 + pub fn capacity(&self) -> NonZeroUsize { + NonZeroUsize::MIN.saturating_add(self.tail.capacity()) } /// Get the last element. Never fails. From aa8aa41c52a9f30b08db2fbe3680932555e24976 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Mon, 13 Jan 2025 09:51:50 +0000 Subject: [PATCH 5/6] Bump to version 0.12.0 Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- CHANGELOG.md | 7 +++++++ Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3ea39..c06e1a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,14 @@ and this library adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 0.12.0 + +### Added +- `bincode` feature flag to enable the use of `bincode-2.0.0`. + +### Changed - `NonEmpty::capacity` returns `NonZeroUsize` +- Fixed the `nonempty!` macro to use the `vec!` macro internally, ensuring that + it compiles with `std` and `no_std`. ## 0.11.0 diff --git a/Cargo.toml b/Cargo.toml index 08aa784..a8b581a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nonempty" -version = "0.11.0" +version = "0.12.0" description = "Correct by construction non-empty vector" authors = ["Alexis Sellier "] edition = "2021" From 95d5cb131262b12bbe55366cbbd48096f9a05493 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Sat, 19 Jul 2025 15:04:26 +0100 Subject: [PATCH 6/6] chore: update github action versions --- .github/workflows/actions.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index e752843..184a2ca 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -14,7 +14,7 @@ jobs: os: ['ubuntu-latest', 'macos-latest'] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build run: cargo build --verbose env: @@ -28,7 +28,7 @@ jobs: os: ['ubuntu-latest', 'macos-latest'] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build run: cargo build --verbose --no-default-features env: @@ -40,7 +40,7 @@ jobs: name: Check rustfmt style && run clippy runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -48,7 +48,7 @@ jobs: components: clippy, rustfmt override: true - name: Cache cargo registry - uses: actions/cache@v1 + uses: actions/cache@v4 with: path: ~/.cargo/registry key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}