genflagged

command module
v0.0.0-...-95b10e5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

README

genflagged: generates compact, uint-based bitflags types out of Go structs with bool fields.

PkgGoDev Go Report Card

It scans the struct type, selects the minimal underlying uint type (uint8, uint16, uint32, or uint64) based on the number of bool fields, and generates a new type with accessor and mutator methods for each field.

The goal is to enable memory-efficient, type-safe, and readable flag representation without sacrificing performance or clarity.

It uses the github.com/asmsh/flagged as the implementation for the bitflags access and modification.

Features:

  • Generates compact types out of struct types that has bool fields, offering a way to replace big structs with a compact uint-based types.
  • Compatible with go:generate for automated code generation.
  • Generates strongly typed flag types, with named methods after each field.
  • Auto-selects optimal uint size (uint8, uint16, uint32, uint64) to fit fields, with optional override.
  • Creates 5 methods per field: Is<Field>(), Set<Field>(), Reset<Field>(), Set<Field>To(bool), Toggle<Field>().
  • Also generates general methods: BitFlags(), Clone(), TypedFlags(), SetTypedFlags().

Installation:

go install github.com/asmsh/flagged/cmd/genflagged@latest

Usage:

Basic usage:

genflagged -type=T

With options:

genflagged [flags] -type T [directory]
genflagged [flags] -type T files... # Must be a single package
Flag Description
-type Comma-separated list of struct types to generate the bitflags types for. (required)
-outType Comma-separated list of names for generated types, matching the values in -type. (default: <type>BitFlags)
Use _ to fall back to default naming for the matching type.
-outFile Name of the output file. (default: <type>_flagged.go, or <type>_flagged_test.go for test types)
-size Force bit size for generated types (one of 8, 16, 32, or 64). (default: auto, and depends on number of bool fields of each type in -type)
-trimprefix Trim prefix from bool field names before generating methods.
-trimsuffix Trim suffix from bool field names before generating methods.
-tags Build tags to be applied during processing.
-verbose Enable extensive logging during processing.

Example:

Given the struct:

package permissions

type Permissions struct {
	Read  bool
	Write bool
	Exec  bool
}

Run:

genflagged -type=Permissions

This generates file permissions_flagged.go in the same directory with:

package permissions

import "github.com/asmsh/flagged"

type PermissionsBitFlags flagged.BitFlags8

func (f *PermissionsBitFlags) IsRead() bool
func (f *PermissionsBitFlags) SetRead() bool
func (f *PermissionsBitFlags) ResetRead() bool
func (f *PermissionsBitFlags) SetReadTo(bool) bool
func (f *PermissionsBitFlags) ToggleRead() bool
// Same for Write and Exec...

func (f *PermissionsBitFlags) BitFlags() flagged.BitFlags
func (f *PermissionsBitFlags) Clone() PermissionsBitFlags
func (f *PermissionsBitFlags) TypedFlags() Permissions
func (f *PermissionsBitFlags) SetTypedFlags(Permissions)

// Plus other helper types and constants...

Or, instead you can have go:generate handle that, such as:

package permissions

//go:generate genflagged -type=Permissions
type Permissions struct {
	Read  bool
	Write bool
	Exec  bool
}

Then run:

go generate

Notes:

  • It's based on the golang.org/x/tools/cmd/stringer source, but with a lot of changes to produce the wanted types.
  • Only struct types that contain at least one bool field are supported.

Documentation

Overview

genflagged generates typed bit flags representations for a struct type T, out of its bool fields. It generates a type with underlying uint type and bit width that's enough to represent all bool fields in type as a bitmask.

The generated type will have methods to access and modify the individual fields based on the fields' names, among other useful methods.

More specifically, for each bool field, 5 different methods are generated:

  • Is<field name>: reports whether the field is set to true or not.
  • Set<field name>: sets the field to true, and returns the old value.
  • Reset<field name>: sets the field to false, and returns the old value.
  • Set<field name>To: sets the field to the new value, and returns the old value.
  • Toggle<field name>: toggles the field's value, and returns the new value.

In addition to 4 other methods for the whole generated type:

  • BitFlags: returns a github.com/asmsh/flagged.BitFlags value, wrapping the receiver value, and exposing a wider range of methods.
  • Clone: returns a copy of the receiver value.
  • TypedFlags: returns a copy of the receiver value as a value of the original type that was used to generate the new flags type.
  • SetTypedFlags: takes a value of the original type and overrides the receiver value based on its fields.

For example, given this type:

package permissions

type Permissions struct {
	Read  bool
	Write bool
	Exec  bool
}

Running this command in the same directory:

go run genflagged -type=Permissions

Will generate file 'permissions_flagged.go', in package 'permissions', containing:

type PermissionsFlags flagged.BitFlags8

func (f *PermissionsFlags) BitFlags() flagged.BitFlags
func (f *PermissionsFlags) Clone() PermissionsFlags
func (f *PermissionsFlags) TypedFlags() Permissions
func (f *PermissionsFlags) SetTypedFlags(Permissions)
func (f *PermissionsFlags) IsRead() bool
func (f *PermissionsFlags) SetRead() bool
func (f *PermissionsFlags) ResetRead() bool
func (f *PermissionsFlags) SetReadTo(bool) bool
func (f *PermissionsFlags) ToggleRead() bool
func (f *PermissionsFlags) IsWrite() bool
func (f *PermissionsFlags) SetWrite() bool
...
func (f *PermissionsFlags) IsExec() bool
func (f *PermissionsFlags) SetExec() bool
...

This enables memory-efficient and type-safe storage of bool configurations, replacing big structs with a compact uint-based types, without sacrificing readability or performance.

It is designed to work with go:generate:

package permissions

//go:generate genflagged -type=Permissions
type Permissions struct {
	Read  bool
	Write bool
	Exec  bool
}

With no arguments, it processes the package in the current directory. Otherwise, the arguments must name a single directory holding a Go package or a set of Go source files that represent a single Go package.

The -type flag accepts a comma-separated list of types, so a single run can generate multiple types. The default output file is 't_flagged.go', where 't' is the lower-cased name of the first type listed. The output file can be overridden with the -outFile flag.

Types can also be declared in tests, in which case type declarations in the non-test package or its test variant are preferred over types defined in the package with suffix "_test". The default output file for type declarations in tests is 't_flagged_test.go' with t picked as above.

The -outType flag accepts a comma-separated list of type names, specifying the names of the generated types. The default name for each provided type T in the -type flag is 'TBitFlags'. The out type names has to match the types provided in the -type flag, in length, with each type name in -outType being the generated type for the source type in the -type flag at the same index. If the '_' is provided as an out type name, the default name is used for its matching source type.

The -size flag accepts one of 8, 16, 32 or 64, specifying the underlying uint type's bit width. The default underlying type's bit width depends on the number of bool fields in each of the source types provided in the -type flag, with:

  • 1 to 8 bool fields: the underlying type is uint8.
  • 9 to 16 bool fields: the underlying type is uint16.
  • 17 to 32 bool fields: the underlying type is uint32.
  • 33 to 64 bool fields: the underlying type is uint64.

The -trimprefix and -trimsuffix flags specifies a prefix and suffix to be removed from each bool field's name, in each source type in the -type flag, before it's used to generated the different methods.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL