Files
upstream-corteza/server/pkg/id/id.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

200 lines
3.0 KiB
Go

package id
import (
"fmt"
"regexp"
"strconv"
)
type (
ID struct {
Num uint64
Str [maxStrIdentifierLength]rune
}
)
const (
maxStrIdentifierLength = 36
)
var (
isNumberRegex = regexp.MustCompile(`^(0|[1-9][0-9]{0,19})$`)
)
func MustNumID(n uint64) ID {
id, err := NumID(n)
if err != nil {
panic(fmt.Sprintf("failed to create NumID: %v", err))
}
return id
}
func NumID(n uint64) (ID, error) {
return ID{Num: n}, nil
}
func MustStrID(s string) ID {
id, err := StrID(s)
if err != nil {
panic(fmt.Sprintf("failed to create StrID: %v", err))
}
return id
}
func StrID(s string) (ID, error) {
if len(s) > maxStrIdentifierLength {
return ID{}, fmt.Errorf("string too long: %s", s)
}
var str [maxStrIdentifierLength]rune
for i, r := range s {
if i < maxStrIdentifierLength {
str[i] = r
}
}
return ID{Str: str}, nil
}
func MustByteID(data []byte) (id ID) {
id, err := ByteID(data)
if err != nil {
panic(fmt.Sprintf("failed to parse ID: %v", err))
}
return id
}
func ByteID(data []byte) (id ID, err error) {
// numeric
if isNumberRegex.MatchString(string(data)) {
num, err := strconv.ParseUint(string(data), 10, 64)
if err != nil {
return id, err
}
id, err = NumID(num)
return id, err
}
// check if strings fit
if len(data) > maxStrIdentifierLength {
return id, fmt.Errorf("string too long: %s", data)
}
id, err = StrID(string(data))
return
}
func (a ID) Equal(b ID) bool {
return a == b
}
func (id ID) IsZero() bool {
return !id.isNum() && !id.isStr()
}
func (id ID) isNum() bool {
return id.Num != 0
}
func (id ID) isStr() bool {
return id.Str != [maxStrIdentifierLength]rune{}
}
func InSlice(needle ID, slice ...ID) bool {
for _, v := range slice {
if v.Equal(needle) {
return true
}
}
return false
}
func RemoveFromSlice(needle ID, slice ...ID) (out []ID) {
if len(slice) == 0 {
return
}
out = make([]ID, 0, len(slice)-1)
for _, i := range slice {
if i.Equal(needle) {
continue
}
out = append(out, i)
}
return
}
func (id ID) Value() string {
if id.isStr() {
return `"` + string(id.String()) + `"`
}
if id.isNum() {
return `"` + String(id.Number()) + `"`
}
// Backward compatibility for empty ID
return `"0"`
}
func (id ID) String() string {
hasValid := false
i := 0
for _, r := range id.Str {
if !hasValid && r != 0 {
hasValid = true
continue
}
if hasValid && r == 0 {
return string(id.Str[:i+1])
}
i++
}
if !hasValid {
return ""
}
return string(id.Str[:])
}
func (id ID) Number() uint64 {
return id.Num
}
// marshal/unmarshal JSON
func (id ID) MarshalJSON() ([]byte, error) {
return []byte(id.Value()), nil
}
func (id *ID) UnmarshalJSON(data []byte) (err error) {
// regex to check if data contains a uint64 or smaller number
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
return nil
}
data = data[1 : len(data)-1]
auxID, err := ByteID(data)
if err != nil {
return
}
*id = auxID
return
}
func StringifySlice(bb ...ID) (out []string) {
for _, b := range bb {
out = append(out, b.Value())
}
return
}