-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #351 from KodrAus/feat/public-traits
Support ejecting flags types from the bitflags macro
- Loading branch information
Showing
67 changed files
with
3,306 additions
and
1,439 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
use std::ops::{BitAnd, BitOr, BitXor, Not}; | ||
|
||
use bitflags::{Flags, Flag, Bits}; | ||
|
||
// Define a custom container that can be used in flags types | ||
// Note custom bits types can't be used in `bitflags!` | ||
// without making the trait impls `const`. This is currently | ||
// unstable | ||
#[derive(Clone, Copy, Debug)] | ||
pub struct CustomBits([bool; 3]); | ||
|
||
impl Bits for CustomBits { | ||
const EMPTY: Self = CustomBits([false; 3]); | ||
|
||
const ALL: Self = CustomBits([true; 3]); | ||
} | ||
|
||
impl PartialEq for CustomBits { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.0 == other.0 | ||
} | ||
} | ||
|
||
impl BitAnd for CustomBits { | ||
type Output = Self; | ||
|
||
fn bitand(self, other: Self) -> Self { | ||
CustomBits([self.0[0] & other.0[0], self.0[1] & other.0[1], self.0[2] & other.0[2]]) | ||
} | ||
} | ||
|
||
impl BitOr for CustomBits { | ||
type Output = Self; | ||
|
||
fn bitor(self, other: Self) -> Self { | ||
CustomBits([self.0[0] | other.0[0], self.0[1] | other.0[1], self.0[2] | other.0[2]]) | ||
} | ||
} | ||
|
||
impl BitXor for CustomBits { | ||
type Output = Self; | ||
|
||
fn bitxor(self, other: Self) -> Self { | ||
CustomBits([self.0[0] & other.0[0], self.0[1] & other.0[1], self.0[2] & other.0[2]]) | ||
} | ||
} | ||
|
||
impl Not for CustomBits { | ||
type Output = Self; | ||
|
||
fn not(self) -> Self { | ||
CustomBits([!self.0[0], !self.0[1], !self.0[2]]) | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct CustomFlags(CustomBits); | ||
|
||
impl CustomFlags { | ||
pub const A: Self = CustomFlags(CustomBits([true, false, false])); | ||
pub const B: Self = CustomFlags(CustomBits([false, true, false])); | ||
pub const C: Self = CustomFlags(CustomBits([false, false, true])); | ||
} | ||
|
||
impl Flags for CustomFlags { | ||
const FLAGS: &'static [Flag<Self>] = &[ | ||
Flag::new("A", Self::A), | ||
Flag::new("B", Self::B), | ||
Flag::new("C", Self::C), | ||
]; | ||
|
||
type Bits = CustomBits; | ||
|
||
fn bits(&self) -> Self::Bits { | ||
self.0 | ||
} | ||
|
||
fn from_bits_retain(bits: Self::Bits) -> Self { | ||
CustomFlags(bits) | ||
} | ||
} | ||
|
||
fn main() { | ||
println!("{:?}", CustomFlags::A.union(CustomFlags::C)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//! An example of implementing the `BitFlags` trait manually for a flags type. | ||
|
||
use std::str; | ||
|
||
use bitflags::bitflags; | ||
|
||
// Define a flags type outside of the `bitflags` macro as a newtype | ||
// It can accept custom derives for libaries `bitflags` doesn't support natively | ||
#[derive(zerocopy::AsBytes, zerocopy::FromBytes)] | ||
#[repr(transparent)] | ||
pub struct ManualFlags(u32); | ||
|
||
// Next: use `impl Flags` instead of `struct Flags` | ||
bitflags! { | ||
impl ManualFlags: u32 { | ||
const A = 0b00000001; | ||
const B = 0b00000010; | ||
const C = 0b00000100; | ||
const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//! An example of implementing the `BitFlags` trait manually for a flags type. | ||
//! | ||
//! This example doesn't use any macros. | ||
|
||
use std::{fmt, str}; | ||
|
||
use bitflags::{Flags, Flag}; | ||
|
||
// First: Define your flags type. It just needs to be `Sized + 'static`. | ||
pub struct ManualFlags(u32); | ||
|
||
// Not required: Define some constants for valid flags | ||
impl ManualFlags { | ||
pub const A: ManualFlags = ManualFlags(0b00000001); | ||
pub const B: ManualFlags = ManualFlags(0b00000010); | ||
pub const C: ManualFlags = ManualFlags(0b00000100); | ||
pub const ABC: ManualFlags = ManualFlags(0b00000111); | ||
} | ||
|
||
// Next: Implement the `BitFlags` trait, specifying your set of valid flags | ||
// and iterators | ||
impl Flags for ManualFlags { | ||
const FLAGS: &'static [Flag<Self>] = &[ | ||
Flag::new("A", Self::A), | ||
Flag::new("B", Self::B), | ||
Flag::new("C", Self::C), | ||
]; | ||
|
||
type Bits = u32; | ||
|
||
fn bits(&self) -> u32 { | ||
self.0 | ||
} | ||
|
||
fn from_bits_retain(bits: u32) -> Self { | ||
Self(bits) | ||
} | ||
} | ||
|
||
// Not required: Add parsing support | ||
impl str::FromStr for ManualFlags { | ||
type Err = bitflags::parser::ParseError; | ||
|
||
fn from_str(input: &str) -> Result<Self, Self::Err> { | ||
bitflags::parser::from_str(input) | ||
} | ||
} | ||
|
||
// Not required: Add formatting support | ||
impl fmt::Display for ManualFlags { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
bitflags::parser::to_writer(self, f) | ||
} | ||
} | ||
|
||
fn main() { | ||
println!("{}", ManualFlags::A.union(ManualFlags::B).union(ManualFlags::C)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.