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

Add a way to not implement the Debug trait #168

Closed
locka99 opened this issue Oct 18, 2018 · 2 comments · Fixed by #282
Closed

Add a way to not implement the Debug trait #168

locka99 opened this issue Oct 18, 2018 · 2 comments · Fixed by #282

Comments

@locka99
Copy link

locka99 commented Oct 18, 2018

I'm using bitflags!() on a large table of u32 status codes where the high 16-bits are a sequential number (1, 2, 3, 4 etc.) and the lower 16-bits are bit flags. Together these are OR'd together to make the code.

https://github.com/locka99/opcua/blob/master/types/src/status_codes.rs

This all works fine except for the default Debug trait implementation which doesn't work properly with sequential values. This is easiest to demonstrate with a cut-down example:

#[macro_use]
extern crate bitflags;

bitflags! {
  pub struct StatusCode: u32 {
    const IS_ERROR                = 0x8000_0000;
    //...
    const Good = 0;
    //...
    const BadEncodingError = 0x8006_0000;
    const BadDecodingError = 0x8007_0000;
  }
}

fn main() {
    println!("{:?}", StatusCode::BadDecodingError);
}

This outputs IS_ERROR | BadEncodingError | BadDecodingError which is inappropriate in my case. I assume it is just doing a bitwise OR to all the values and appending them to the output string. I would like to be able to implement my own Debug trait and not generate the default one.

For example the bitflags!() macro could have a pattern or form which excludes emitting the Debug trait, ... pub struct (nodebug) StatusCode

Note I can override the fmt::Display trait for discrete cases where I need to print the StatusCode but it doesn't help when debug dumping out structs that have StatusCode as a member.

@KodrAus
Copy link
Member

KodrAus commented Oct 18, 2018

Hi @locka99 👋

Hmm, I think your best bet here might be to wrap those generated flags in a newtype, and implement your Error, Debug, and Display traits on that newtype:

bitflags! {
    struct StatusCode: u32 { ... }
}

pub struct Error(StatusCode);

That way you've got full control over what traits will be implemented and how they should work.

@npmccallum
Copy link

npmccallum commented Dec 16, 2019

@locka99 What you really have is a 32-bit struct with two members: one is an enum and the other is a bitflag.

#[repr(u16)]
enum Code {
        GoodSubscriptionTransferred = 0x002D,
        GoodCompletesAsynchronously = 0x002E,
        GoodOverload = 0x002F,
        // ...
}

bitflags! {
    pub struct StatusCode: u16 {
        const HISTORICAL_CALCULATED   = 0x0001;
        const HISTORICAL_INTERPOLATED = 0x0002;
        const HISTORICAL_RESERVED     = 0x0003;
        const HISTORICAL_PARTIAL      = 0x0004;
        // ...
    }
}

#[repr(align(4))]
struct Status {
    code: Code,
    flags: Flags,
}

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 a pull request may close this issue.

3 participants