bitfield

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2025 License: MIT Imports: 1 Imported by: 0

README

Bitfield

This library is for working with enum of binary representation.
The most often case that we're working this is RBAC but usable in any other cases that's needed to set some rules with bits.

With this we can abstract out the numerical enum and some bits trickery while still using the same underlying efficiency and performance.

Our current bitfield is each limited to 32 fields that should be usable in most cases.

How to use

In order to be convertible between value and sets, we need to have our enum implements the interface Enumerator which simply returning the possible values of our enums.

For example we have enum as below:

type myenum int
const (
    field1 myenum = iota
    field2
    field3
    field4
)

func (myenum) Enums() []myenum {
    return []myenum{field1, field2, field3, field4}
}

Note: we can also to have myenum to implement fmt.Stringer

With above defined, we can use it as

bits := bitfield.New[myenum]() // in this case we set all fields 0
if bits.Value() != 0 { panic(bits.Value()) }
bits = bitfield.New[myenum](field1, field4)
if bits.Value() != 9 { panic(bits.Value()) }
if bits.Has(field2) { panic("expected to don't have field2") }
if !bits.Has(field1) { panic("expected to have field1") }

Our bitfield package is simple and only has several exported API viz:

  1. New[Enumerator[E]](e ...E) Bitfield[E] to initiate Bitfield object.
  2. Bitfield.Has[E](e ...E) bool to test whether e is/are set in Bitfield object.
  3. Bitfield.Include[E](e ...E) to set our bit field.
  4. Bitfield.Exclude[E](e ...E) to clear out bit field.
  5. Bitfield.Value() uint32 to get its integer representation.
  6. From[Enumerator[E]](uint) Bitfield[E] to convert our value to Bitfield object.

Install

Simply

go get github.com/mashingan/bitfield

or

within file just import it and run go mod tidy will automatically add this lib to your project.

Example

Let's create bits roles in our RBAC.

1. Bit 1: Identify whether the user is superadmin
2. Bit 2: Identify whether the user is admin
3. Bit 3: Identify whether the user is user
4. Bit 4: Read permission
5. Bit 5: Write permission
6. Bit 6: Delete permission

Using above roles, we can use Bitfield as below

package main

import (
	"log"

	"github.com/mashingan/bitfield"
)

/*
   1. Bit 1: Identify whether the user is superadmin
   2. Bit 2: Identify whether the user is admin
   3. Bit 3: Identify whether the user is user
   4. Bit 4: Read permission
   5. Bit 5: Write permission
   6. Bit 6: Delete permission
*/

type RoleAcc byte

// our enum bitfield bits definition
const (
	raSuperAdmin RoleAcc = iota
	raAdmin
	raUser
	raRead
	raWrite
	raDelete
)

func (RoleAcc) Enums() []RoleAcc {
	return []RoleAcc{
		raSuperAdmin, raAdmin, raUser,
		raRead, raWrite, raDelete,
	}
}

var rolestr = map[RoleAcc]string{
	raSuperAdmin: "super_admin",
	raAdmin:      "admin",
	raUser:       "user",
	raRead:       "read",
	raWrite:      "write",
	raDelete:     "delete",
}

func (r RoleAcc) String() string {
	return rolestr[r]
}

func main() {
	// let's create a super admin only
	user := bitfield.New[RoleAcc](raSuperAdmin)
	if user.Has(raAdmin) {
		log.Fatal("expected user only has role super admin, got admin")
	}

	if len(user.Sets()) != 1 {
		log.Fatal("expected user only has role sets: [super_admin], got:", user.Sets())
	}

	if user.Value() != 1 {
		log.Fatal("expected user role value is 1, got:", user.Value())
	}

	user.Exclude(raSuperAdmin)
	if user.Has(raSuperAdmin) {
		log.Fatal("expected user doesn't have any role, got superadmin")
	}

	if len(user.Sets()) != 0 {
		log.Fatal("expected user has empty role sets, got:", user.Sets())
	}

	if user.Value() != 0 {
		log.Fatal("expected user role value is 0, got:", user.Value())
	}

	user = bitfield.From[RoleAcc](58) // re-create from value
	log.Println("user sets:", user.Sets())
	if !user.Has(raAdmin) {
		log.Fatal("expected user is admin")
	}

	if !user.Has(raRead) || !user.Has(raWrite) || !user.Has(raDelete) {
		log.Fatal("expected user able to read, write, and delete, got:", user.Sets())
	}
}

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bitfield

type Bitfield[E Enumerator[E]] struct {
	// contains filtered or unexported fields
}

func From

func From[E Enumerator[E]](v uint32) Bitfield[E]

func New

func New[E Enumerator[E]](els ...E) Bitfield[E]

func (*Bitfield[E]) Exclude

func (b *Bitfield[E]) Exclude(els ...E)

func (Bitfield[E]) Has

func (b Bitfield[E]) Has(e E) bool

func (*Bitfield[E]) Include

func (b *Bitfield[E]) Include(els ...E)

func (Bitfield[E]) Sets

func (b Bitfield[E]) Sets() []E

func (Bitfield[E]) Value

func (b Bitfield[E]) Value() uint32

type Enumerator

type Enumerator[E any] interface {
	constraints.Unsigned
	Enums() []E
}

Jump to

Keyboard shortcuts

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