mirror of
https://github.com/aykhans/go-utils.git
synced 2026-01-14 10:51:21 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 530d0cb977 | |||
| 8018b27873 |
50
README.md
50
README.md
@@ -5,7 +5,7 @@ A collection of generic utility functions for Go projects.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go get github.com/aykhans/go-utils
|
go get go.aykhans.me/go-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
@@ -16,7 +16,7 @@ Generic type conversion utilities.
|
|||||||
|
|
||||||
**ToPtr** - Convert any value to a pointer
|
**ToPtr** - Convert any value to a pointer
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/common"
|
import "go.aykhans.me/go-utils/common"
|
||||||
|
|
||||||
num := 42
|
num := 42
|
||||||
ptr := common.ToPtr(num) // *int
|
ptr := common.ToPtr(num) // *int
|
||||||
@@ -24,7 +24,7 @@ ptr := common.ToPtr(num) // *int
|
|||||||
|
|
||||||
**IsNilOrZero** - Check if a pointer is nil or points to a zero value
|
**IsNilOrZero** - Check if a pointer is nil or points to a zero value
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/common"
|
import "go.aykhans.me/go-utils/common"
|
||||||
|
|
||||||
var ptr *int
|
var ptr *int
|
||||||
common.IsNilOrZero(ptr) // true (nil pointer)
|
common.IsNilOrZero(ptr) // true (nil pointer)
|
||||||
@@ -42,7 +42,7 @@ String parsing utilities with generic type support.
|
|||||||
|
|
||||||
**ParseString** - Parse string to various types
|
**ParseString** - Parse string to various types
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/parser"
|
import "go.aykhans.me/go-utils/parser"
|
||||||
|
|
||||||
num, err := parser.ParseString[int]("42")
|
num, err := parser.ParseString[int]("42")
|
||||||
duration, err := parser.ParseString[time.Duration]("5s")
|
duration, err := parser.ParseString[time.Duration]("5s")
|
||||||
@@ -72,7 +72,7 @@ Slice manipulation utilities.
|
|||||||
|
|
||||||
**Cycle** - Create an infinite cycler through items
|
**Cycle** - Create an infinite cycler through items
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/slice"
|
import "go.aykhans.me/go-utils/slice"
|
||||||
|
|
||||||
next := slice.Cycle(1, 2, 3)
|
next := slice.Cycle(1, 2, 3)
|
||||||
fmt.Println(next()) // 1
|
fmt.Println(next()) // 1
|
||||||
@@ -93,7 +93,7 @@ Map utility functions.
|
|||||||
|
|
||||||
**InitMap** - Initialize a map pointer if nil
|
**InitMap** - Initialize a map pointer if nil
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/maps"
|
import "go.aykhans.me/go-utils/maps"
|
||||||
|
|
||||||
var m map[string]int
|
var m map[string]int
|
||||||
maps.InitMap(&m)
|
maps.InitMap(&m)
|
||||||
@@ -114,7 +114,7 @@ Number utility functions.
|
|||||||
|
|
||||||
**NumLen** - Calculate the number of digits in an integer
|
**NumLen** - Calculate the number of digits in an integer
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/number"
|
import "go.aykhans.me/go-utils/number"
|
||||||
|
|
||||||
number.NumLen(42) // returns 2
|
number.NumLen(42) // returns 2
|
||||||
number.NumLen(-128) // returns 3
|
number.NumLen(-128) // returns 3
|
||||||
@@ -133,68 +133,68 @@ Supported types: `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uin
|
|||||||
|
|
||||||
Advanced error handling utilities.
|
Advanced error handling utilities.
|
||||||
|
|
||||||
**HandleError** - Process errors with custom matchers
|
**Handle** - Process errors with custom matchers
|
||||||
```go
|
```go
|
||||||
import "github.com/aykhans/go-utils/errors"
|
import "go.aykhans.me/go-utils/errors"
|
||||||
|
|
||||||
handled, result := errors.HandleError(err,
|
handled, result := errors.Handle(err,
|
||||||
errors.OnSentinelError(io.EOF, func(e error) error {
|
errors.OnSentinel(io.EOF, func(e error) error {
|
||||||
return nil // EOF is expected, ignore it
|
return nil // EOF is expected, ignore it
|
||||||
}),
|
}),
|
||||||
errors.OnCustomError(func(e *CustomError) error {
|
errors.OnType(func(e *CustomError) error {
|
||||||
return fmt.Errorf("custom error: %w", e)
|
return fmt.Errorf("custom error: %w", e)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
**HandleErrorOrDie** - Handle errors or panic if unhandled
|
**MustHandle** - Handle errors or panic if unhandled
|
||||||
```go
|
```go
|
||||||
result := errors.HandleErrorOrDie(err,
|
result := errors.MustHandle(err,
|
||||||
errors.OnSentinelError(context.Canceled, func(e error) error {
|
errors.OnSentinel(context.Canceled, func(e error) error {
|
||||||
return fmt.Errorf("operation canceled")
|
return fmt.Errorf("operation canceled")
|
||||||
}),
|
}),
|
||||||
) // Panics if err doesn't match any handler
|
) // Panics if err doesn't match any handler
|
||||||
```
|
```
|
||||||
|
|
||||||
**HandleErrorOrDefault** - Handle errors with a default fallback
|
**HandleOr** - Handle errors with a default fallback
|
||||||
```go
|
```go
|
||||||
result := errors.HandleErrorOrDefault(err,
|
result := errors.HandleOr(err,
|
||||||
func(e error) error {
|
func(e error) error {
|
||||||
// Default handler for unmatched errors
|
// Default handler for unmatched errors
|
||||||
return fmt.Errorf("unexpected error: %w", e)
|
return fmt.Errorf("unexpected error: %w", e)
|
||||||
},
|
},
|
||||||
errors.OnSentinelError(context.Canceled, func(e error) error {
|
errors.OnSentinel(context.Canceled, func(e error) error {
|
||||||
return fmt.Errorf("operation canceled")
|
return fmt.Errorf("operation canceled")
|
||||||
}),
|
}),
|
||||||
errors.OnCustomError(func(e *ValidationError) error {
|
errors.OnType(func(e *ValidationError) error {
|
||||||
return fmt.Errorf("validation failed: %w", e)
|
return fmt.Errorf("validation failed: %w", e)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pass nil to suppress unmatched errors
|
// Pass nil to suppress unmatched errors
|
||||||
result := errors.HandleErrorOrDefault(err, nil,
|
result := errors.HandleOr(err, nil,
|
||||||
errors.OnSentinelError(io.EOF, func(e error) error {
|
errors.OnSentinel(io.EOF, func(e error) error {
|
||||||
return errors.New("EOF handled")
|
return errors.New("EOF handled")
|
||||||
}),
|
}),
|
||||||
) // Returns nil for unmatched errors
|
) // Returns nil for unmatched errors
|
||||||
```
|
```
|
||||||
|
|
||||||
**OnSentinelError** - Create matcher for sentinel errors (like `io.EOF`)
|
**OnSentinel** - Create matcher for sentinel errors (like `io.EOF`)
|
||||||
```go
|
```go
|
||||||
matcher := errors.OnSentinelError(io.EOF, func(e error) error {
|
matcher := errors.OnSentinel(io.EOF, func(e error) error {
|
||||||
log.Println("reached end of file")
|
log.Println("reached end of file")
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
**OnCustomError** - Create matcher for custom error types
|
**OnType** - Create matcher for custom error types
|
||||||
```go
|
```go
|
||||||
type ValidationError struct {
|
type ValidationError struct {
|
||||||
Field string
|
Field string
|
||||||
Msg string
|
Msg string
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher := errors.OnCustomError(func(e *ValidationError) error {
|
matcher := errors.OnType(func(e *ValidationError) error {
|
||||||
log.Printf("validation failed on field %s", e.Field)
|
log.Printf("validation failed on field %s", e.Field)
|
||||||
return fmt.Errorf("invalid input: %w", e)
|
return fmt.Errorf("invalid input: %w", e)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ type ErrorMatcher struct {
|
|||||||
// or (false, nil) if no matcher matches the error.
|
// or (false, nil) if no matcher matches the error.
|
||||||
// If err is nil, returns (true, nil).
|
// If err is nil, returns (true, nil).
|
||||||
//
|
//
|
||||||
|
// Deprecated: HandleError is deprecated and will be removed in a future release.
|
||||||
|
// Use Handle instead, which provides the same functionality.
|
||||||
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// handled, result := HandleError(err,
|
// handled, result := HandleError(err,
|
||||||
@@ -58,11 +61,31 @@ func HandleError(err error, matchers ...ErrorMatcher) (bool, error) {
|
|||||||
return false, err // No matcher found
|
return false, err // No matcher found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle processes an error against a list of matchers and executes the appropriate handler.
|
||||||
|
// It returns (true, handlerResult) if a matching handler is found and executed,
|
||||||
|
// or (false, nil) if no matcher matches the error.
|
||||||
|
// If err is nil, returns (true, nil).
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// handled, result := Handle(err,
|
||||||
|
// OnSentinel(io.EOF, func(e error) error {
|
||||||
|
// return nil // EOF is expected, ignore it
|
||||||
|
// }),
|
||||||
|
// OnType(func(e *CustomError) error {
|
||||||
|
// return fmt.Errorf("custom error: %w", e)
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
var Handle = HandleError
|
||||||
|
|
||||||
// HandleErrorOrDie processes an error against a list of matchers and executes the appropriate handler.
|
// HandleErrorOrDie processes an error against a list of matchers and executes the appropriate handler.
|
||||||
// If a matching handler is found, it returns the handler's result.
|
// If a matching handler is found, it returns the handler's result.
|
||||||
// If no matcher matches the error, it panics with a descriptive message.
|
// If no matcher matches the error, it panics with a descriptive message.
|
||||||
// This function is useful when all expected error types must be handled explicitly.
|
// This function is useful when all expected error types must be handled explicitly.
|
||||||
//
|
//
|
||||||
|
// Deprecated: HandleErrorOrDie is deprecated and will be removed in a future release.
|
||||||
|
// Use MustHandle instead, which provides the same functionality.
|
||||||
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// result := HandleErrorOrDie(err,
|
// result := HandleErrorOrDie(err,
|
||||||
@@ -81,6 +104,23 @@ func HandleErrorOrDie(err error, matchers ...ErrorMatcher) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustHandle processes an error against a list of matchers and executes the appropriate handler.
|
||||||
|
// If a matching handler is found, it returns the handler's result.
|
||||||
|
// If no matcher matches the error, it panics with a descriptive message.
|
||||||
|
// This function is useful when all expected error types must be handled explicitly.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// result := MustHandle(err,
|
||||||
|
// OnSentinel(context.Canceled, func(e error) error {
|
||||||
|
// return fmt.Errorf("operation canceled")
|
||||||
|
// }),
|
||||||
|
// OnType(func(e *ValidationError) error {
|
||||||
|
// return fmt.Errorf("validation failed: %w", e)
|
||||||
|
// }),
|
||||||
|
// ) // Panics if err doesn't match any handler
|
||||||
|
var MustHandle = HandleErrorOrDie
|
||||||
|
|
||||||
// HandleErrorOrDefault processes an error against a list of matchers and executes the appropriate handler.
|
// HandleErrorOrDefault processes an error against a list of matchers and executes the appropriate handler.
|
||||||
// If a matching handler is found, it returns the handler's result.
|
// If a matching handler is found, it returns the handler's result.
|
||||||
// If no matcher matches the error, it executes the default handler (dft) and returns its result.
|
// If no matcher matches the error, it executes the default handler (dft) and returns its result.
|
||||||
@@ -88,6 +128,9 @@ func HandleErrorOrDie(err error, matchers ...ErrorMatcher) error {
|
|||||||
// This function is useful when you want to handle specific error cases explicitly
|
// This function is useful when you want to handle specific error cases explicitly
|
||||||
// while providing a fallback handler for all other errors.
|
// while providing a fallback handler for all other errors.
|
||||||
//
|
//
|
||||||
|
// Deprecated: HandleErrorOrDefault is deprecated and will be removed in a future release.
|
||||||
|
// Use HandleOr instead, which provides the same functionality.
|
||||||
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// result := HandleErrorOrDefault(err,
|
// result := HandleErrorOrDefault(err,
|
||||||
@@ -120,6 +163,36 @@ func HandleErrorOrDefault(err error, dft ErrorHandler, matchers ...ErrorMatcher)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleOr processes an error against a list of matchers and executes the appropriate handler.
|
||||||
|
// If a matching handler is found, it returns the handler's result.
|
||||||
|
// If no matcher matches the error, it executes the default handler (dft) and returns its result.
|
||||||
|
// If dft is nil, unmatched errors return nil (effectively suppressing the error).
|
||||||
|
// This function is useful when you want to handle specific error cases explicitly
|
||||||
|
// while providing a fallback handler for all other errors.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// result := HandleOr(err,
|
||||||
|
// func(e error) error {
|
||||||
|
// // Default handler for unmatched errors
|
||||||
|
// return fmt.Errorf("unexpected error: %w", e)
|
||||||
|
// },
|
||||||
|
// OnSentinel(context.Canceled, func(e error) error {
|
||||||
|
// return fmt.Errorf("operation canceled")
|
||||||
|
// }),
|
||||||
|
// OnType(func(e *ValidationError) error {
|
||||||
|
// return fmt.Errorf("validation failed: %w", e)
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// // Suppress unmatched errors by passing nil as default handler
|
||||||
|
// result := HandleOr(err, nil,
|
||||||
|
// OnSentinel(io.EOF, func(e error) error {
|
||||||
|
// return errors.New("EOF handled")
|
||||||
|
// }),
|
||||||
|
// ) // Returns nil for unmatched errors
|
||||||
|
var HandleOr = HandleErrorOrDefault
|
||||||
|
|
||||||
// OnSentinelError creates an ErrorMatcher for sentinel errors.
|
// OnSentinelError creates an ErrorMatcher for sentinel errors.
|
||||||
// Sentinel errors are predefined error values that are compared using errors.Is.
|
// Sentinel errors are predefined error values that are compared using errors.Is.
|
||||||
//
|
//
|
||||||
@@ -130,6 +203,9 @@ func HandleErrorOrDefault(err error, dft ErrorHandler, matchers ...ErrorMatcher)
|
|||||||
// The handler function receives the original error and can return a new error
|
// The handler function receives the original error and can return a new error
|
||||||
// or nil to suppress it.
|
// or nil to suppress it.
|
||||||
//
|
//
|
||||||
|
// Deprecated: OnSentinelError is deprecated and will be removed in a future release.
|
||||||
|
// Use OnSentinel instead, which provides the same functionality.
|
||||||
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// matcher := OnSentinelError(io.EOF, func(e error) error {
|
// matcher := OnSentinelError(io.EOF, func(e error) error {
|
||||||
@@ -144,6 +220,24 @@ func OnSentinelError(sentinelErr error, handler ErrorHandler) ErrorMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnSentinel creates an ErrorMatcher for sentinel errors.
|
||||||
|
// Sentinel errors are predefined error values that are compared using errors.Is.
|
||||||
|
//
|
||||||
|
// This is used with Handle or MustHandle to match specific error
|
||||||
|
// values like io.EOF, context.Canceled, or custom sentinel errors defined with
|
||||||
|
// errors.New or fmt.Errorf.
|
||||||
|
//
|
||||||
|
// The handler function receives the original error and can return a new error
|
||||||
|
// or nil to suppress it.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// matcher := OnSentinel(io.EOF, func(e error) error {
|
||||||
|
// log.Println("reached end of file")
|
||||||
|
// return nil // suppress EOF error
|
||||||
|
// })
|
||||||
|
var OnSentinel = OnSentinelError
|
||||||
|
|
||||||
// OnCustomError creates an ErrorMatcher for custom error types.
|
// OnCustomError creates an ErrorMatcher for custom error types.
|
||||||
// Custom error types are struct types that implement the error interface,
|
// Custom error types are struct types that implement the error interface,
|
||||||
// and are matched using errors.As to unwrap error chains.
|
// and are matched using errors.As to unwrap error chains.
|
||||||
@@ -155,6 +249,9 @@ func OnSentinelError(sentinelErr error, handler ErrorHandler) ErrorMatcher {
|
|||||||
// This is particularly useful for handling errors with additional context or data,
|
// This is particularly useful for handling errors with additional context or data,
|
||||||
// such as validation errors, network errors, or domain-specific errors.
|
// such as validation errors, network errors, or domain-specific errors.
|
||||||
//
|
//
|
||||||
|
// Deprecated: OnCustomError is deprecated and will be removed in a future release.
|
||||||
|
// Use OnType instead, which provides the same functionality.
|
||||||
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// type ValidationError struct {
|
// type ValidationError struct {
|
||||||
@@ -183,3 +280,32 @@ func OnCustomError[T error](handler func(T) error) ErrorMatcher {
|
|||||||
IsSentinel: false,
|
IsSentinel: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnType creates an ErrorMatcher for custom error types.
|
||||||
|
// Custom error types are struct types that implement the error interface,
|
||||||
|
// and are matched using errors.As to unwrap error chains.
|
||||||
|
//
|
||||||
|
// The type parameter T specifies the error type to match. The handler function
|
||||||
|
// receives the unwrapped typed error, allowing you to access type-specific fields
|
||||||
|
// and methods.
|
||||||
|
//
|
||||||
|
// This is particularly useful for handling errors with additional context or data,
|
||||||
|
// such as validation errors, network errors, or domain-specific errors.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type ValidationError struct {
|
||||||
|
// Field string
|
||||||
|
// Msg string
|
||||||
|
// }
|
||||||
|
// func (e *ValidationError) Error() string {
|
||||||
|
// return fmt.Sprintf("%s: %s", e.Field, e.Msg)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// matcher := OnType(func(e *ValidationError) error {
|
||||||
|
// log.Printf("validation failed on field %s: %s", e.Field, e.Msg)
|
||||||
|
// return fmt.Errorf("invalid input: %w", e)
|
||||||
|
// })
|
||||||
|
func OnType[T error](handler func(T) error) ErrorMatcher {
|
||||||
|
return OnCustomError(handler)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user