package actor import ( "encoding/json" "fmt" "git.k6n.net/mats/platform/uid" ) // GrainId is a 64-bit grain identifier with a compact base62 string form. type GrainId uid.ID // String returns the canonical base62 encoding. func (id GrainId) String() string { return uid.ID(id).String() } // MarshalJSON encodes the id as a JSON string. func (id GrainId) MarshalJSON() ([]byte, error) { return json.Marshal(uid.ID(id).String()) } // UnmarshalJSON decodes from a base62 JSON string. func (id *GrainId) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } parsed, ok := ParseGrainId(s) if !ok { return fmt.Errorf("invalid grain id: %q", s) } *id = parsed return nil } // NewGrainId generates a new cryptographically random non-zero 64-bit id. func NewGrainId() (GrainId, error) { id, err := uid.New() if err != nil { return 0, fmt.Errorf("NewGrainId: %w", err) } return GrainId(id), nil } // MustNewGrainId panics if generation fails. func MustNewGrainId() GrainId { id, err := NewGrainId() if err != nil { panic(err) } return id } // ParseGrainId parses a base62 string into a GrainId. func ParseGrainId(s string) (GrainId, bool) { id, ok := uid.Parse(s) return GrainId(id), ok } // MustParseGrainId panics on invalid base62 input. func MustParseGrainId(s string) GrainId { id, ok := ParseGrainId(s) if !ok { panic(fmt.Sprintf("invalid grain id: %q", s)) } return id }