Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

re-implemented Debug to show the bits field of the internal struct as… #9

Merged
merged 1 commit into from
Jun 1, 2015
Merged

Conversation

CraZySacX
Copy link
Contributor

… binary (8-bits wide)

Fixes issue #8 by re-implementing Debug to a simpler representation:

$BitFlags { bits: 0bXXXXXXXX }

If this isn't preferable, I would recommend dropping the general Debug impl and let everyone implement their own.

@alexcrichton
Copy link
Contributor

Thanks! I think I'll remove the 10-character width limit for now (as it could be larger or smaller), but I'll do that locally.

alexcrichton added a commit that referenced this pull request Jun 1, 2015
re-implemented Debug to show the bits field of the internal struct as…
@alexcrichton alexcrichton merged commit 30958f6 into bitflags:master Jun 1, 2015
@emberian
Copy link
Contributor

emberian commented Jun 3, 2015

This sucks a lot for my usecases at least, since a non-symbolic representation is impossible to decipher (I have 61 cases right now). I don't see a good way to do it in the macro though in the face of #8.

let out = format!("{} {{ bits: {:#010b} }}",
stringify!($BitFlags),
self.bits);
f.write_str(&out[..])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General design note: there’s no need to create an intermediate string; you should use write! in here:

                write!(f, "{} {{ bits: {:#010b} }}",
                       stringify!($BitFlags),
                       self.bits)

chris-morgan added a commit to chris-morgan/bitflags that referenced this pull request Jun 26, 2015
`Debug` was implemented using the nice readable flag names in bitflags#7, but
the flag names were removed in bitflags#9 because it used `$Flags` which broke
trivial `#[cfg]`-based removal of flags. Changing `.contains($Flag)` to
`.contains($BitFlags { bits: $value })` instead (akin to what `.all()`
did) would have fixed that issue, allowing a friendly `Debug` again, but
then I found a further improvement to make, because the `#[cfg]`
behaviour was still off, as a flag’s value was still written out
regardless of the `#[cfg]` attribute, so if *it* contained stuff that
didn’t exist `bitflags!` would still blow up. This is inconsistent with
how such things work in Rust proper, so I’ve fixed it.

The fix is rather convoluted, involving a dummy module, a bunch of dummy
constants, a nested function and glob imports, but it works, avoiding
referring to `$value` successfully. This change causes this to work:

```rust
bitflags! {
    flags Foo: u32 {
        #[cfg(a)]
        const A = 0b1,
        #[cfg(a)]
        const B = A.bits,  // or anything else that is `#[cfg(a)]`
    }
}
```

(Formerly `all()` was still trying to use `A.bits` when `cfg(not(a))`
and thus `A` wasn’t defined.)

This change allows `#[cfg]` on a flag to work like it should, allowing
it to depend on things that don’t exist unless the conditions are met.
Sure, that seems a pretty rare case for flags, but it’s real. Beyond
the style of example above, my imagined scenario is a -sys crate
having declared certain flag values, but only when certain features are
enabled, and so when defining the bitflags in another crate (for the
-sys crate doesn’t use bitflags) you can only use those values with the
appropriate features.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants