package uuid import ( "encoding/json" "fmt" "io" "strconv" "time" fuuid "github.com/gofrs/uuid/v5" ) var Nil = UUID{} type UUIDList = []UUID type UUID struct { fuuid.UUID } func New() UUID { return UUID{fuuid.Must(fuuid.NewV7())} } func NewFromTime(t time.Time) UUID { gen := fuuid.NewGenWithOptions( fuuid.WithEpochFunc(func() time.Time { return t }), ) return UUID{fuuid.Must(gen.NewV7())} } func NewP() *UUID { return &UUID{fuuid.Must(fuuid.NewV7())} } func FromString(text string) (UUID, error) { u, err := fuuid.FromString(text) if err != nil { return Nil, err } return UUID{u}, nil } func MustFromString(text string) UUID { u, err := fuuid.FromString(text) if err != nil { panic(err) } return UUID{u} } func FromBytes(input []byte) (UUID, error) { u, err := fuuid.FromBytes(input) if err != nil { return Nil, err } return UUID{u}, nil } func (a *UUID) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } if s == "" { a.UUID = fuuid.Nil return nil } return a.UUID.Parse(s) } func (a UUID) MarshalJSON() ([]byte, error) { if a.IsNil() { return json.Marshal("") } return json.Marshal(a.UUID) } // UnmarshalGQL implements the graphql.Unmarshaler interface func (u *UUID) UnmarshalGQL(v interface{}) error { id, ok := v.(string) if !ok { return fmt.Errorf("uuid must be a string") } return u.Parse(id) } // MarshalGQL implements the graphql.Marshaler interface func (u UUID) MarshalGQL(w io.Writer) { b := []byte(strconv.Quote(u.String())) _, err := w.Write(b) if err != nil { panic(err) } }