How it works...

The bitflags! macro lets you define all of your flags and their underlying type (in our case, this is u32)[4 to 15]. They are written in ALL_CAPS because they are constants. We can also define collections of flags this way, as we did with ALL[10]. We could have added additional combinations, for example:

const SPICY = Self::PEPPER.bits | Self::CHILI.bits;

The macro then creates a struct with the specified members for you and implements a bunch of traits for it in order to enable the familiar |, &, -, and ! notations [37 to 40] and pretty printing. You can still access the raw bits used in the background directly over the member of the same name.

Note that, when printing, flag combinations will be listed separately. For instance, look at the output in line [47]. After setting all possible flags in the field to active, it will pretty print itself as the following:

Custom spice after adding saffron: SALT | PEPPER | CHILI | SAFFRON | ALL

A useful method to additionally define on a bit field is clear()[19]. This hides the underlying bits from the user and is nicely readable.

With the aforementioned binary operators, you can perform set operations on your bit field [37 to 40]. These are the same operations as the ones you can perform on a HashSet and are explained with a nice diagram in Chapter 2Working with Collections; Using a HashSet.

Working with single flags in the bit field is also very easy. insert() sets a flag in the field to active [45], remove() sets it to inactive [50], and toggle flips it from active to inactive and vice versa [48]. If you don't yet know whether you're going to insert or remove a flag, as is the case with unpredictable user input, you can use set() to explicitly set the activation of a flag to either true or false [55].

You can check whether a certain flag is active by calling contains() [56]. This also works for another bit field or a flag combination. This means that the following is also valid:

if custom.contains(Spices::SALT | Spices::PEPPER) {
println!("The custom spice contains both salt and pepper");
}

Additionally, you can use intersects() to check whether any flags in two-bit fields match.

Last but not least, you can deserialize raw bytes into your generated bit field struct by calling from_bits() on it [62]. This will check whether every bit actually corresponds to a flag and return None otherwise. You can skip the error checking and simply ignore invalid bits with from_bits_truncate() if you're absolutely 100% sure that the data has to be valid.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.142.2