diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f6138548..f4226652 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -73,6 +73,23 @@ jobs: command: bench args: --no-run + msrv: + name: MSRV + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install tombl + run: cargo install tombl + + - name: Smoke test + run: | + eval $(tombl -e msrv=package.rust-version Cargo.toml) + rustup update $msrv + cd ./tests/smoke-test + cargo +$msrv build + embedded: name: Build (embedded) runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 674d0289..1873cc0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,47 @@ +# 2.0.0 + +## What's Changed +* Fix a typo and call out MSRV bump by @KodrAus in https://github.com/bitflags/bitflags/pull/259 +* BitFlags trait by @arturoc in https://github.com/bitflags/bitflags/pull/220 +* Add a hidden trait to discourage manual impls of BitFlags by @KodrAus in https://github.com/bitflags/bitflags/pull/261 +* Sanitize `Ok` by @konsumlamm in https://github.com/bitflags/bitflags/pull/266 +* Fix bug in `Debug` implementation by @konsumlamm in https://github.com/bitflags/bitflags/pull/268 +* Fix a typo in the generated documentation by @wackbyte in https://github.com/bitflags/bitflags/pull/271 +* Use SPDX license format by @atouchet in https://github.com/bitflags/bitflags/pull/272 +* serde tests fail in CI by @arturoc in https://github.com/bitflags/bitflags/pull/277 +* Fix beta test output by @KodrAus in https://github.com/bitflags/bitflags/pull/279 +* Add example to the README.md file by @tiaanl in https://github.com/bitflags/bitflags/pull/270 +* Iterator over all the enabled options by @arturoc in https://github.com/bitflags/bitflags/pull/278 +* from_bits_(truncate) fail with composite flags by @arturoc in https://github.com/bitflags/bitflags/pull/276 +* Add more platform coverage to CI by @KodrAus in https://github.com/bitflags/bitflags/pull/280 +* rework the way cfgs are handled by @KodrAus in https://github.com/bitflags/bitflags/pull/281 +* Split generated code into two types by @KodrAus in https://github.com/bitflags/bitflags/pull/282 +* expose bitflags iters using nameable types by @KodrAus in https://github.com/bitflags/bitflags/pull/286 +* Support creating flags from their names by @KodrAus in https://github.com/bitflags/bitflags/pull/287 +* Update README.md by @KodrAus in https://github.com/bitflags/bitflags/pull/288 +* Prepare for 2.0.0-rc.1 release by @KodrAus in https://github.com/bitflags/bitflags/pull/289 +* Add missing "if" to contains doc-comment in traits.rs by @rusty-snake in https://github.com/bitflags/bitflags/pull/291 +* Forbid unsafe_code by @fintelia in https://github.com/bitflags/bitflags/pull/294 +* serde: enable no-std support by @nim65s in https://github.com/bitflags/bitflags/pull/296 +* Add a parser for flags formatted as bar-separated-values by @KodrAus in https://github.com/bitflags/bitflags/pull/297 +* Prepare for 2.0.0-rc.2 release by @KodrAus in https://github.com/bitflags/bitflags/pull/299 +* Use strip_prefix instead of starts_with + slice by @QuinnPainter in https://github.com/bitflags/bitflags/pull/301 +* Fix up some clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/302 +* Prepare for 2.0.0-rc.3 release by @KodrAus in https://github.com/bitflags/bitflags/pull/303 +* feat: Add minimum permissions to rust.yml workflow by @gabibguti in https://github.com/bitflags/bitflags/pull/305 + +## New Contributors +* @wackbyte made their first contribution in https://github.com/bitflags/bitflags/pull/271 +* @atouchet made their first contribution in https://github.com/bitflags/bitflags/pull/272 +* @tiaanl made their first contribution in https://github.com/bitflags/bitflags/pull/270 +* @rusty-snake made their first contribution in https://github.com/bitflags/bitflags/pull/291 +* @fintelia made their first contribution in https://github.com/bitflags/bitflags/pull/294 +* @nim65s made their first contribution in https://github.com/bitflags/bitflags/pull/296 +* @QuinnPainter made their first contribution in https://github.com/bitflags/bitflags/pull/301 +* @gabibguti made their first contribution in https://github.com/bitflags/bitflags/pull/305 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/1.3.2...2.0.0 + # 2.0.0-rc.3 ## What's Changed diff --git a/Cargo.toml b/Cargo.toml index ded3a800..cccc0089 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,9 @@ name = "bitflags" # NB: When modifying, also modify: # 1. html_root_url in lib.rs # 2. number in readme (for breaking changes) -version = "2.0.0-rc.3" -edition = "2018" +version = "2.0.0" +edition = "2021" +rust-version = "1.56.0" authors = ["The Rust Project Developers"] license = "MIT OR Apache-2.0" keywords = ["bit", "bitmask", "bitflags", "flags"] diff --git a/README.md b/README.md index a619d0a6..413c60ec 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -bitflags = "2.0.0-rc.3" +bitflags = "2.0.0" ``` and this to your source code: @@ -56,4 +56,5 @@ fn main() { ## Rust Version Support -The minimum supported Rust version is 1.46 due to use of associated constants and const functions. +The minimum supported Rust version is documented in the `Cargo.toml` file. +This may be bumped in minor releases as necessary. diff --git a/src/internal.rs b/src/internal.rs index fdda1fd9..ff75be37 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -20,7 +20,10 @@ macro_rules! __declare_internal_bitflags { bits: $T, } - $iter_vis struct $Iter($IterNames); + $iter_vis struct $Iter { + inner: $IterNames, + done: bool, + } $iter_names_vis struct $IterNames { idx: usize, @@ -245,7 +248,10 @@ macro_rules! __impl_internal_bitflags { #[inline] pub const fn iter(&self) -> $Iter { - $Iter(self.iter_names()) + $Iter { + inner: self.iter_names(), + done: false, + } } #[inline] @@ -348,7 +354,22 @@ macro_rules! __impl_internal_bitflags { type Item = $BitFlags; fn next(&mut self) -> $crate::__private::core::option::Option { - self.0.next().map(|(_, value)| value) + match self.inner.next().map(|(_, value)| value) { + $crate::__private::core::option::Option::Some(value) => $crate::__private::core::option::Option::Some(value), + $crate::__private::core::option::Option::None if !self.done => { + self.done = true; + + // After iterating through valid names, if there are any bits left over + // then return one final value that includes them. This makes `into_iter` + // and `from_iter` roundtrip + if self.inner.state != $InternalBitFlags::empty() { + $crate::__private::core::option::Option::Some($BitFlags::from_bits_retain(self.inner.state.bits())) + } else { + $crate::__private::core::option::Option::None + } + }, + _ => $crate::__private::core::option::Option::None, + } } } diff --git a/src/lib.rs b/src/lib.rs index fdd102c9..47539a93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1498,6 +1498,17 @@ mod tests { assert_eq!(iter.next().unwrap(), ("ONE", Flags::ONE)); assert_eq!(iter.next().unwrap(), ("THREE", Flags::THREE)); assert_eq!(iter.next(), None); + + let flags = Flags::from_bits_retain(0b1000_0000); + assert_eq!(flags.into_iter().count(), 1); + assert_eq!(flags.iter_names().count(), 0); + } + + #[test] + fn into_iter_from_iter_roundtrip() { + let flags = Flags::ABC | Flags::from_bits_retain(0b1000_0000); + + assert_eq!(flags, flags.into_iter().collect::()); } #[test] diff --git a/src/parser.rs b/src/parser.rs index 38bf6683..944517f5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,18 +1,30 @@ //! Parsing flags from text. //! -//! `bitflags` defines the following whitespace-insensitive grammar for flags formatted +//! `bitflags` defines the following *whitespace-insensitive*, *case-sensitive* grammar for flags formatted //! as text: //! //! - _Flags:_ (_Flag_)`|`* //! - _Flag:_ _Identifier_ | _HexNumber_ //! - _Identifier:_ Any Rust identifier -//! - _HexNumber_: `0x`([0-9a-zA-Z])* +//! - _HexNumber_: `0x`([0-9a-fA-F])* //! //! As an example, this is how `Flags::A | Flags::B | 0x0c` can be represented as text: //! //! ```text //! A | B | 0x0c //! ``` +//! +//! Alternatively, it could be represented without whitespace: +//! +//! ```text +//! A|B|0x0C +//! ``` +//! +//! Note that identifiers are *case-sensitive*, so the following is *not equivalent*: +//! +//! ```text +//! a | b | 0x0c +//! ``` #![allow(clippy::let_unit_value)]