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 ¶
- func Coalesce[T comparable](arr ...T) T
- func Deref[T any](v *T) T
- func GetEnvOrDefault(names ...string) string
- func Interpolate(arg string, vars interface{}) string
- func InterpolateStrings(arg []string, vars interface{}) []string
- func NormalizeVersion(version string) string
- func ParseTime(t string) *time.Time
- func Ptr[T any](value T) *T
- func RandomKey(length int) string
- func RandomString(length int) string
- func ShortTimestamp() string
- func Stringify(val any) (string, error)
- type NamedLock
- type Unlocker
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 ¶
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 ¶
Interpolate templatises the string using the vars as the context
func InterpolateStrings ¶
InterpolateStrings templatises each string in the slice using the vars as the context
func NormalizeVersion ¶ added in v1.1.1
NormalizeVersion appends "v" to version string if it's not exist
func ParseTime ¶ added in v1.39.0
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 RandomString ¶
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
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
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
}
}()