// Code generated by fidlgen; DO NOT EDIT.

package bits

import (
	_bindings "syscall/zx/fidl"
)

var _ _bindings.Bits = MyBits(0)

type MyBits uint32

const (
	MyBitsMyFirstBit MyBits = 1
	MyBitsMyOtherBit MyBits = 2
	MyBitsMask       MyBits = 4
	MyBits_Mask      MyBits = 7
)

func (_ MyBits) I_BitsMask() MyBits {
	return MyBits_Mask
}

func (_ MyBits) I_BitsIsStrict() bool {
	return true
}

func (x MyBits) HasUnknownBits() bool {
	return x.GetUnknownBits() != 0
}

func (x MyBits) GetUnknownBits() uint64 {
	return uint64(^MyBits_Mask & x)
}

func (x MyBits) InvertBits() MyBits {
	return MyBits_Mask & ^x
}

// HasBits validates that all flipped bits in the mask are set.
func (x MyBits) HasBits(mask MyBits) bool {
	return mask|x == x
}

// ClearBits ensures all flipped bits in the mask are unset.
func (x MyBits) ClearBits(mask MyBits) MyBits {
	return ^mask & x
}

func (x MyBits) String() string {
	switch x {
	case 1:
		return "MyFirstBit"
	case 2:
		return "MyOtherBit"
	case 4:
		return "Mask"
	}
	return "Unknown"
}

var _ _bindings.Bits = StrictBits(0)

type StrictBits uint64

const (
	StrictBitsSmallest StrictBits = 1
	StrictBitsBiggest  StrictBits = 9223372036854775808
	StrictBits_Mask    StrictBits = 9223372036854775809
)

func (_ StrictBits) I_BitsMask() StrictBits {
	return StrictBits_Mask
}

func (_ StrictBits) I_BitsIsStrict() bool {
	return true
}

func (x StrictBits) HasUnknownBits() bool {
	return x.GetUnknownBits() != 0
}

func (x StrictBits) GetUnknownBits() uint64 {
	return uint64(^StrictBits_Mask & x)
}

func (x StrictBits) InvertBits() StrictBits {
	return StrictBits_Mask & ^x
}

// HasBits validates that all flipped bits in the mask are set.
func (x StrictBits) HasBits(mask StrictBits) bool {
	return mask|x == x
}

// ClearBits ensures all flipped bits in the mask are unset.
func (x StrictBits) ClearBits(mask StrictBits) StrictBits {
	return ^mask & x
}

func (x StrictBits) String() string {
	switch x {
	case 1:
		return "Smallest"
	case 9223372036854775808:
		return "Biggest"
	}
	return "Unknown"
}

var _ _bindings.Bits = FlexibleBits(0)

type FlexibleBits uint64

const (
	FlexibleBitsSmallest FlexibleBits = 1
	FlexibleBitsBiggest  FlexibleBits = 9223372036854775808
	FlexibleBits_Mask    FlexibleBits = 9223372036854775809
)

func (_ FlexibleBits) I_BitsMask() FlexibleBits {
	return FlexibleBits_Mask
}

func (_ FlexibleBits) I_BitsIsStrict() bool {
	return false
}

func (x FlexibleBits) HasUnknownBits() bool {
	return x.GetUnknownBits() != 0
}

func (x FlexibleBits) GetUnknownBits() uint64 {
	return uint64(^FlexibleBits_Mask & x)
}

func (x FlexibleBits) InvertBits() FlexibleBits {
	return FlexibleBits_Mask & ^x
}

// HasBits validates that all flipped bits in the mask are set.
func (x FlexibleBits) HasBits(mask FlexibleBits) bool {
	return mask|x == x
}

// ClearBits ensures all flipped bits in the mask are unset.
func (x FlexibleBits) ClearBits(mask FlexibleBits) FlexibleBits {
	return ^mask & x
}

func (x FlexibleBits) String() string {
	switch x {
	case 1:
		return "Smallest"
	case 9223372036854775808:
		return "Biggest"
	}
	return "Unknown"
}
