xuid

package module
v0.0.0-...-1d2d653 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2025 License: MIT Imports: 6 Imported by: 0

README

XUID

Go Reference

A Go package for generating compact, sortable UUID-based identifiers with optional string prefixes and base58 encoding.

Features

  • 🎯 Sortable UUIDs: Generate UUIDv7 identifiers that maintain chronological order
  • 🎲 Random UUIDs: Generate UUIDv4 identifiers for non-sortable use cases
  • 🏷️ Optional Prefixes: Add human-readable prefixes to your identifiers (e.g., user_, order_)
  • 📦 Compact Encoding: Uses base58 encoding for shorter, URL-safe strings
  • 🔄 JSON Support: Built-in JSON marshaling and unmarshaling
  • 🗄️ SQL Database Support: Seamless integration with SQL databases (PostgreSQL, MySQL, etc.)
  • Type Safety: Strong typing with validation and parsing utilities

Installation

go get github.com/47monad/xuid

Quick Start

package main

import (
    "fmt"
    "github.com/47monad/xuid"
)

func main() {
    // Generate a sortable XUID with prefix
    id := xuid.MustNewSortable("user")
    fmt.Println(id.String()) // Output: user_8M7Qq2vR3kGbF9wN5pL2xA

    // Generate a random XUID
    randomID, _ := xuid.NewRandom("session")
    fmt.Println(randomID.String()) // Output: session_5K9Mm1nP7jDcE8vL3qR6yB

    // Parse an existing XUID string
    parsed, _ := xuid.Parse("user_8M7Qq2vR3kGbF9wN5pL2xA")
    fmt.Println(parsed.GetPrefix()) // Output: user
}

Usage

Creating XUIDs
Sortable UUIDs (UUIDv7)
// With error handling
id, err := xuid.NewSortable("order")
if err != nil {
    log.Fatal(err)
}

// Without error handling (panics on error)
id := xuid.MustNewSortable("order")
Random UUIDs (UUIDv4)
id, err := xuid.NewRandom("session")
if err != nil {
    log.Fatal(err)
}

// Without error handling (panics on error)
id := xuid.MustNewRandom("order")
From Existing UUID
import "github.com/google/uuid"

existingUUID := uuid.New()
id, err := xuid.NewWith(existingUUID, "custom")
Nil UUID
nilID, err := xuid.NilUUID()
Working with XUIDs
String Representation
id := xuid.MustNewSortable("user")
fmt.Println(id.String()) // user_8M7Qq2vR3kGbF9wN5pL2xA
Access Properties
id := xuid.MustNewSortable("user")

// Get the underlying UUID
uuid := id.GetUUID()

// Get the prefix
prefix := id.GetPrefix() // "user"

// Check UUID version
isSortable := id.IsSortable() // true for UUIDv7
isRandom := id.IsRandom()     // true for UUIDv4
Parsing and Validation
// Parse a XUID string
id, err := xuid.Parse("user_8M7Qq2vR3kGbF9wN5pL2xA")
if err != nil {
    log.Fatal(err)
}

// Validate a XUID string
if xuid.IsValid("user_8M7Qq2vR3kGbF9wN5pL2xA") {
    fmt.Println("Valid XUID")
}

// Check if empty
if xuid.IsEmpty(id) {
    fmt.Println("Empty XUID")
}
Comparison
id1 := xuid.MustNewSortable("user")
id2 := xuid.MustNewSortable("user")

if id1.Equal(id2) {
    fmt.Println("XUIDs are equal")
}
JSON Support

XUIDs can be seamlessly marshaled to and from JSON:

type User struct {
    ID   xuid.XUID `json:"id"`
    Name string    `json:"name"`
}

user := User{
    ID:   xuid.MustNewSortable("user"),
    Name: "John Doe",
}

// Marshal to JSON
data, _ := json.Marshal(user)
// {"id":"user_8M7Qq2vR3kGbF9wN5pL2xA","name":"John Doe"}

// Unmarshal from JSON
var parsed User
json.Unmarshal(data, &parsed)
SQL Support

XUIDs integrate seamlessly with SQL databases such as PostgreSQL and MySQL. However, there are a few caveats to keep in mind:

  • Only the UUID bytes are stored — The 16-byte UUID is stored in the database as a []byte (e.g., BYTEA in PostgreSQL or BINARY(16) in MySQL). This ensures efficient storage and indexing.
  • Prefixes are not stored — If your application relies on the XUID prefix (e.g., "file_", "user_") for querying or categorization, you’ll need to store the prefix in a separate column.

Format

XUIDs follow this format:

  • Without prefix: 8M7Qq2vR3kGbF9wN5pL2xA
  • With prefix: prefix_8M7Qq2vR3kGbF9wN5pL2xA

The identifier part is a base58-encoded UUID, making it:

  • Shorter than standard UUID strings (22 characters vs 36)
  • URL-safe (no special characters that need encoding)
  • Case-sensitive but avoids confusing characters (0, O, I, l)

Error Handling

The package defines specific error types:

var (
    ErrInvalidUUIDString = errors.New("UUID string is invalid")
    ErrParse             = errors.New("XUID string cannot be parsed")
)

Dependencies

  • github.com/google/uuid - UUID generation and manipulation
  • github.com/btcsuite/btcd/btcutil/base58 - Base58 encoding

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Documentation

Overview

Package xuid provides a compact, type-safe identifier system built on UUIDs.

XUID combines the robustness of UUIDs with practical enhancements: - Sortable identifiers using UUIDv7 for chronological ordering - Optional string prefixes for human-readable context (e.g., "user_", "order_") - Base58 encoding for shorter, URL-safe representations - Built-in JSON marshaling and unmarshaling support

Example usage:

// Create a sortable identifier with prefix
userID := xuid.MustNewSortable("user")
fmt.Println(userID.String()) // user_8M7Qq2vR3kGbF9wN5pL2xA

// Parse from string
parsed, err := xuid.Parse("user_8M7Qq2vR3kGbF9wN5pL2xA")
if err != nil {
	log.Fatal(err)
}
fmt.Println(parsed.GetPrefix()) // user

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidUUIDString = errors.New("UUID string is invalid")
	ErrParse             = errors.New("XUID string cannot be parsed")
)

Functions

func IsEmpty

func IsEmpty(xid XUID) bool

func IsValid

func IsValid(idstr string) bool

Types

type XUID

type XUID struct {
	// contains filtered or unexported fields
}

func Must

func Must(xid XUID, err error) XUID

func MustNewRandom

func MustNewRandom(prefix string) XUID

func MustNewSortable

func MustNewSortable(prefix string) XUID

func MustParse

func MustParse(idstr string) XUID

func New

func New() (XUID, error)

func NewRandom

func NewRandom(prefix string) (XUID, error)

func NewSortable

func NewSortable(prefix string) (XUID, error)

func NewWith

func NewWith(id uuid.UUID, prefix string) (XUID, error)

func NilUUID

func NilUUID() (XUID, error)

func Parse

func Parse(idstr string) (XUID, error)

func (XUID) Equal

func (x XUID) Equal(y XUID) bool

func (XUID) GetPrefix

func (x XUID) GetPrefix() string

func (XUID) GetUUID

func (x XUID) GetUUID() uuid.UUID

func (XUID) IsRandom

func (x XUID) IsRandom() bool

func (XUID) IsSortable

func (x XUID) IsSortable() bool

func (XUID) MarshalJSON

func (x XUID) MarshalJSON() ([]byte, error)

func (*XUID) Scan

func (x *XUID) Scan(value interface{}) error

Scan implements the sql.Scanner interface. This allows XUID to be loaded from SQL databases. Note: The prefix information is lost when loading from database. You should reconstruct XUIDs with their appropriate prefixes after loading.

func (*XUID) SetPrefix

func (x *XUID) SetPrefix(prefix string) *XUID

SetPrefix sets the prefix field to the specified prefix. This is useful when loading XUIDs from database and need to restore the prefix.

func (XUID) String

func (x XUID) String() string

func (*XUID) UnmarshalJSON

func (x *XUID) UnmarshalJSON(data []byte) error

func (XUID) Value

func (x XUID) Value() (driver.Value, error)

Value implements the driver.Valuer interface. This allows XUID to be stored in SQL databases as UUID.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL