#How to define enum flag

1 messages · Page 1 of 1 (latest)

wise lake
#

I'm writing a zig app to list V4L2 device capabilities
They are defined in /usr/include/linux/videodev2.h in field capabilities of struct v4l2_capability where each bit represents a capability. So essentially a bit flag.

How does it translate to zig? Should I use packed struct ? If so could you show an example of how to display capabilitties from an int?

brave forge
#

Are you writing bindings? If not, you can use them same way as in C
If you want to represent the bitlflags as packed struct for nicer interface then that's possible indeed.

#
const Capabilities = packed struct (u32) {
  video_capture: bool = false,
  video_output: bool = false,
  video_overlay: bool = false,
  vbi_capture: bool = false,
  vbi_output: bool = false,
  // and so on ...
};
#

you can @bitCast this struct into/from u32 then

wise lake
#

awesome. Thanks!

#

it looks like there are 29 possibilities. I had to do something like:

const Capabilities = packed struct(u32) {
    //...
    DEVICE_CAPS: bool,
    RESERVED1: bool,
    RESERVED2: bool,
    RESERVED3: bool,

is there another way?

#

Even something like:

const Capabilities = packed struct(u32) {
    //...
    DEVICE_CAPS: bool,
    RESERVED: u3,
}

seems a bit awkward

undone sluice
#

Maybe @Vector of bools will work?

brave forge
#

you need to pad rest of the struct

#

RESERVED: u3 is fine

#

or I usually do _: u3

#

also the zig way is to use lowercase field names

wise lake
#

Actually it looks like this:

const Capabilities = packed struct(u32) {
  // .. some caps
  RESERVED1: bool,
  // .. more caps
  RESERVED1: bool,
}

so I cannot use the _: bool syntax, can I?

brave forge
#

nah, have to give unique name sadly

wise lake
#

is there a generic way to print the fields with true value? Something like an instrospection api?

brave forge
#
pub fn format(self: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
        inline for (std.meta.fields(@This()) |field| {
          try writer.print("{s}: {}", .{field.name, @field(self, field.name)};
        }
    }
};

something like that, untested (prints all fields and their variable)

wise lake
#

I got something working:

fn fmt(comptime T: type, value: T, writer: anytype) !void {
    inline for (std.meta.fields(T)) |field| {
        if (@field(value, field.name)) {
            try writer.print("{s}, ", .{field.name});
        }
    }
}