func (v *V0) Domain() string {
	if v == nil {
		return ""
	}
	return v.entityDomain
}
Domain implements ID.domain
package bloxid
import (
	"bytes"
	"encoding/base32"
	"encoding/hex"
	"errors"
	"fmt"
	"strings"
)
const (
	UniqueIDEncodedMinCharSize = 16
	VersionUnknown Version = iota
	Version0       Version = iota
	IDSchemeRandom = "random"
)
type Version uint8
func (v Version) String() string {
	name, ok := version_name[v]
	if !ok {
		return version_name[VersionUnknown]
	}
	return name
}
var version_name = map[Version]string{
	VersionUnknown: "unknown",
	Version0:       "blox0",
}
var name_version = map[string]Version{
	"unknown": VersionUnknown,
	"blox0":   Version0,
}
var (
	ErrInvalidVersion      error = errors.New("invalid bloxid version")
	ErrInvalidEntityDomain error = errors.New("entity domain must be non-empty")
	ErrInvalidEntityType   error = errors.New("entity type must be non-empty")
	ErrInvalidUniqueIDLen  error = errors.New("unique ID did not meet minimum length requirements")
	ErrIDEmpty error = errors.New("empty bloxid")
	ErrV0Parts error = errors.New("invalid number of parts found")
)
const (
	V0Delimiter   = "."
	bloxidTypeLen = 4
)
type EncodeDecodeOpts func(o *V0Options)
func NewV0(bloxid string, fnOpts ...EncodeDecodeOpts) (*V0, error) {
	opts := generateV0Options(fnOpts...)
	if len(strings.TrimSpace(bloxid)) == 0 {
		return generateV0(opts)
	}
	return parseV0(bloxid, opts.hashidSalt)
}
func generateV0Options(fnOpts ...EncodeDecodeOpts) *V0Options {
	var opts *V0Options = new(V0Options)
	for _, fn := range fnOpts {
		fn(opts)
	}
	return opts
}
func parseV0(bloxid, salt string) (*V0, error) {
	if len(bloxid) == 0 {
		return nil, ErrIDEmpty
	}
	if err := validateV0(bloxid); err != nil {
		return nil, err
	}
	parts := strings.Split(bloxid, V0Delimiter)
	v0 := &V0{
		version:      name_version[parts[0]],
		entityDomain: parts[1],
		entityType:   parts[2],
		realm:        parts[3],
		encoded:      parts[4],
	}
	decodedTall := strings.ToUpper(parts[4])
	decoded, err := base32.StdEncoding.DecodeString(decodedTall)
	if err != nil {
		return nil, fmt.Errorf("unable to decode id: %s", err)
	}
	switch {
	case bytes.HasPrefix(decoded, hashIDPrefixBytes):
		var hashed string
		hashed = strings.TrimSpace(string(decoded[bloxidTypeLen:]))
		v0.hashIDInt64, err = getInt64FromHashID(hashed, salt)
		if err != nil {
			return nil, err
		}
		v0.decoded = fmt.Sprintf("%v", v0.hashIDInt64)
		v0.scheme = IDSchemeHashID
	case bytes.HasPrefix(decoded, extrinsicIDPrefixBytes):
		v0.decoded = strings.TrimSpace(string(decoded[bloxidTypeLen:]))
		v0.scheme = IDSchemeExtrinsic
	default:
		if len(v0.encoded) < DefaultUniqueIDEncodedCharSize {
			return nil, ErrInvalidUniqueIDLen
		}
		v0.decoded = hex.EncodeToString(decoded)
		v0.scheme = IDSchemeRandom
	}
	return v0, nil
}
func validateV0(bloxid string) error {
	parts := strings.Split(bloxid, V0Delimiter)
	if len(parts) != 5 {
		return ErrV0Parts
	}
	if ver := parts[0]; ver != Version0.String() {
		return ErrInvalidVersion
	}
	if entityDomain := parts[1]; len(entityDomain) == 0 {
		return ErrInvalidEntityDomain
	}
	if entityType := parts[2]; len(entityType) == 0 {
		return ErrInvalidEntityType
	}
	if len(parts[4]) < UniqueIDEncodedMinCharSize {
		return ErrInvalidUniqueIDLen
	}
	return nil
}
var _ ID = &V0{}
type V0 struct {
	version      Version
	entityDomain string
	entityType   string
	realm        string
	decoded      string
	encoded      string
	hashIDInt64  int64
	scheme       string
}
func (v *V0) String() string {
	s := []string{
		v.Version(),
		v.entityDomain,
		v.entityType,
		v.realm,
		v.encoded,
	}
	return strings.Join(s, V0Delimiter)
}
func (v *V0) Version() string {
	if v == nil {
		return VersionUnknown.String()
	}
	return v.version.String()
}