utils

package
v1.43.2 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2025 License: Apache-2.0 Imports: 14 Imported by: 51

Documentation

Overview

Package utils provides common utility functions for Go applications.

The package includes helpers for pointer operations, string manipulation, randomization, template interpolation, time parsing, and named locks. These utilities address common patterns in Go programming and reduce boilerplate code.

Key features:

  • Generic pointer and dereference utilities
  • Coalesce function for finding first non-zero value
  • Environment variable helpers
  • Random string and key generation
  • Template string interpolation
  • Flexible time parsing with multiple formats
  • Named lock implementation for synchronization

Pointer utilities:

// Create pointer to value
strPtr := utils.Ptr("hello")
intPtr := utils.Ptr(42)

// Safely dereference (returns zero value if nil)
val := utils.Deref(strPtr) // "hello"
val2 := utils.Deref(nil)   // "" (zero value)

Coalesce example:

// Returns first non-zero value
result := utils.Coalesce("", "", "value", "ignored") // "value"
port := utils.Coalesce(0, 0, 8080, 9090)            // 8080

Random generation:

// Generate random hex key
apiKey := utils.RandomKey(32)

// Generate random alphanumeric string
sessionID := utils.RandomString(16)

Template interpolation:

vars := map[string]string{"name": "World", "time": "today"}
result := utils.Interpolate("Hello {{.name}}, how are you {{.time}}?", vars)
// "Hello World, how are you today?"

Time parsing:

// Parse time with automatic format detection
t := utils.ParseTime("2023-12-25T10:30:00Z")        // RFC3339
t2 := utils.ParseTime("2023-12-25 10:30:00")       // MySQL format
t3 := utils.ParseTime("2023-12-25")                // Date only

Named locks:

lock := &utils.NamedLock{}
if unlocker := lock.TryLock("resource-1", 5*time.Second); unlocker != nil {
	defer unlocker.Release()
	// Critical section
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Coalesce added in v1.11.0

func Coalesce[T comparable](arr ...T) T

Coalesce returns the first non-zero value from the provided arguments. This is similar to the COALESCE function in SQL and the nullish coalescing operator (??) in other languages.

Example:

// String coalescing
name := utils.Coalesce("", "", "John", "Jane") // Returns "John"

// Number coalescing
port := utils.Coalesce(0, 0, 8080, 9090)      // Returns 8080

// With variables
result := utils.Coalesce(config.URL, os.Getenv("API_URL"), "http://localhost")

func Deref added in v1.13.0

func Deref[T any](v *T) T

Deref safely dereferences a pointer, returning the zero value if the pointer is nil. This prevents nil pointer panics and simplifies nil checking.

Example:

var strPtr *string = nil
val := utils.Deref(strPtr)  // Returns "" (zero value for string)

strPtr = utils.Ptr("hello")
val = utils.Deref(strPtr)   // Returns "hello"

func GetEnvOrDefault

func GetEnvOrDefault(names ...string) string

GetEnvOrDefault returns the value of the first non-empty environment variable from the provided list of names. This is useful for checking multiple possible environment variable names or providing fallback options.

Example:

// Check multiple possible names
dbHost := utils.GetEnvOrDefault("DATABASE_HOST", "DB_HOST", "POSTGRES_HOST")

// With fallback handling
apiKey := utils.GetEnvOrDefault("API_KEY", "SECRET_KEY")
if apiKey == "" {
	apiKey = "default-key"
}

func Interpolate

func Interpolate(arg string, vars interface{}) string

Interpolate templatises the string using the vars as the context

func InterpolateStrings

func InterpolateStrings(arg []string, vars interface{}) []string

InterpolateStrings templatises each string in the slice using the vars as the context

func NormalizeVersion added in v1.1.1

func NormalizeVersion(version string) string

NormalizeVersion appends "v" to version string if it's not exist

func ParseTime added in v1.39.0

func ParseTime(t string) *time.Time

ParseTime attempts to parse a time string using multiple common formats. It tries various formats in order and returns the first successful parse. Returns nil if no format matches.

Supported formats:

  • RFC3339: "2006-01-02T15:04:05Z07:00"
  • RFC3339Nano: "2006-01-02T15:04:05.999999999Z07:00"
  • ANSIC: "Mon Jan _2 15:04:05 2006"
  • DateTime: "2006-01-02 15:04:05"
  • DateOnly: "2006-01-02"
  • ISO8601 without timezone: "2006-01-02T15:04:05"
  • MySQL datetime: "2006-01-02 15:04:05"

Example:

t1 := utils.ParseTime("2023-12-25T10:30:00Z")      // RFC3339
t2 := utils.ParseTime("2023-12-25 10:30:00")       // MySQL format
t3 := utils.ParseTime("2023-12-25")                // Date only
t4 := utils.ParseTime("Mon Jan 2 15:04:05 2006")   // ANSIC

if t := utils.ParseTime(userInput); t != nil {
	fmt.Printf("Parsed time: %v\n", t)
} else {
	fmt.Println("Invalid time format")
}

func Ptr added in v1.11.0

func Ptr[T any](value T) *T

Ptr returns a pointer to the given value. This is a generic helper function useful for creating pointers to literals or values that need to be passed as pointers to functions.

Example:

// Instead of:
temp := "hello"
ptr := &temp

// You can write:
ptr := utils.Ptr("hello")

func RandomKey

func RandomKey(length int) string

func RandomString

func RandomString(length int) string

RandomString returns a random string consisting of the characters in randomChars, with the length customized by the parameter

func ShortTimestamp

func ShortTimestamp() string

ShortTimestamp returns a shortened timestamp using week of year + day of week to represent a day of the e.g. 1st of Jan on a Tuesday is 13

func Stringify added in v1.6.4

func Stringify(val any) (string, error)

Stringify converts the given value to a string. If the value is already a string, it is returned as is.

Types

type NamedLock added in v1.19.0

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

NamedLock provides a mechanism for acquiring locks by name, allowing different parts of the code to synchronize on string identifiers. This is useful for resource-based locking where you want to ensure exclusive access to resources identified by strings (e.g., file paths, user IDs, resource names).

The implementation uses semaphores internally, providing timeout support and preventing goroutine leaks.

func (*NamedLock) TryLock added in v1.19.0

func (n *NamedLock) TryLock(name string, timeout time.Duration) Unlocker

TryLock attempts to acquire a lock with the given name within the specified timeout. If successful, it returns an Unlocker that must be used to release the lock. If the lock cannot be acquired within the timeout, it returns nil.

The lock is exclusive - only one goroutine can hold a lock with a given name at any time.

Example:

lock := &NamedLock{}

// Try to acquire lock with 5-second timeout
if unlocker := lock.TryLock("user-123", 5*time.Second); unlocker != nil {
	defer unlocker.Release()
	// Critical section - exclusive access to user-123
	updateUser("123")
} else {
	// Could not acquire lock within timeout
	return errors.New("resource is locked")
}

Multiple locks example:

// Different names don't block each other
go func() {
	if u := lock.TryLock("resource-A", time.Second); u != nil {
		defer u.Release()
		// Work with resource A
	}
}()

go func() {
	if u := lock.TryLock("resource-B", time.Second); u != nil {
		defer u.Release()
		// Work with resource B
	}
}()

type Unlocker added in v1.19.0

type Unlocker interface {
	Release()
}

Unlocker provides a method to release a lock. It follows the standard pattern for lock guards in Go.

Jump to

Keyboard shortcuts

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