goodies
packageAPI reference for the goodies
package.
Imports
(11)ErrorHandler
ErrorHandler is the protocol for handling errors, use this to implement
custom error handling logic.
type ErrorHandler interface
Methods
NoErrorHandler
NoErrorHandler is a default error handler that does nothing, useful when
you don’t need to handle errors.
type NoErrorHandler struct
Methods
Parameters
Returns
func (*NoErrorHandler) HandleError(args ...interface{}) error
{
return nil
}
ErrorHandlerFn
ErrorHandlerFn is an error handler that implements the ErrorHandler
protocol, use this to create custom error handling logic.
type ErrorHandlerFn func(args ...interface{}) error
CleanupQueue
CleanupQueue is a priority queue that runs cleanup tasks in order of
priority and uses the defined error handler to handle errors.
type CleanupQueue struct
Methods
Add adds a new task to the cleanup queue.
Parameters
func (*CleanupQueue) Add(task func(args ...interface{}) error, args []interface{}, priority int, errorHandler ErrorHandler, ignoreErrorHandlerFailure bool)
{
cleanupTask := &CleanupTask{
Task: task,
Args: args,
Priority: priority,
ErrorHandler: errorHandler,
IgnoreErrorHandlerFailure: ignoreErrorHandlerFailure,
}
heap.Push(&q.tasks, cleanupTask)
}
Run runs the cleanup queue and executes all the tasks in order of priority. It returns an error if any of the tasks encounter an error, including the error handler function, unless the task is marked to ignore error handler failures.
Returns
func (*CleanupQueue) Run() error
{
for q.tasks.Len() > 0 {
task := heap.Pop(&q.tasks).(*CleanupTask)
err := task.Task(task.Args...)
if err != nil {
errHandle := task.ErrorHandler.HandleError(task.Args...)
if errHandle != nil {
if !task.IgnoreErrorHandlerFailure {
return fmt.Errorf("error handling failed: %v", errHandle)
}
}
}
}
return nil
}
Fields
| Name | Type | Description |
|---|---|---|
| tasks | cleanupHeap |
NewCleanupQueue
NewCleanupQueue creates a new cleanup queue.
Returns
func NewCleanupQueue() *CleanupQueue
{
q := &CleanupQueue{}
heap.Init(&q.tasks)
return q
}
CleanupTask
CleanupTask is a task that defines a cleanup task to be run in the cleanup
queue. It has a priority, a task to run, a list of arguments, an error
handler to handle errors, and a flag to ignore error handler failures.
type CleanupTask struct
Fields
| Name | Type | Description |
|---|---|---|
| Priority | int | |
| Task | func(args ...interface{}) error | |
| Args | []interface{} | |
| ErrorHandler | ErrorHandler | |
| IgnoreErrorHandlerFailure | bool | |
| index | int |
cleanupHeap
type cleanupHeap []*CleanupTask
EventManager
EventManager is a simple event manager that allows subscribing to events
and notifying them, so that multiple parts of the code can be notified
when an event happens and act accordingly.
type EventManager struct
Methods
Subscribe subscribes to an event type and returns a subscription ID, use this ID to unsubscribe from the event later.
Parameters
Returns
func (*EventManager) Subscribe(eventType string, handler EventHandler) int
{
em.mu.Lock()
defer em.mu.Unlock()
if em.listeners[eventType] == nil {
em.listeners[eventType] = make(map[int]EventHandler)
}
em.nextID++
id := em.nextID
em.listeners[eventType][id] = handler
return id
}
subID := eventManager.Subscribe("testEvent", func(data interface{}) {
fmt.Println("Event happened:", data)
})
fmt.Println("Subscribed with ID:", subID)
Unsubscribe unsubscribes from an event type using its subscription ID
Parameters
func (*EventManager) Unsubscribe(eventType string, id int)
{
em.mu.Lock()
defer em.mu.Unlock()
if handlers, ok := em.listeners[eventType]; ok {
delete(handlers, id)
}
}
subID := eventManager.Subscribe("testEvent", func(data interface{}) {
fmt.Println("Event happened:", data)
})
fmt.Println("Subscribed with ID:", subID)
eventManager.Unsubscribe("testEvent", subID)
Notify notifies an event type with some data, all the handlers subscribed to the event type will be called with the data.
Parameters
func (*EventManager) Notify(eventType string, data interface{})
{
em.mu.RLock()
defer em.mu.RUnlock()
if handlers, ok := em.listeners[eventType]; ok {
for _, handler := range handlers {
handler(data)
}
}
}
eventManager.Notify("testEvent", "testData")
Fields
| Name | Type | Description |
|---|---|---|
| mu | sync.RWMutex | |
| listeners | map[string]map[int]EventHandler | |
| nextID | int |
EventHandler
EventHandler is the protocol for handling events, use this to implement
custom event handling logics for your application.
type EventHandler func(interface{})
NewEventManager
NewEventManager creates a new event manager.
Returns
func NewEventManager() *EventManager
{
return &EventManager{
listeners: make(map[string]map[int]EventHandler),
}
}
Example
eventManager := goodies.NewEventManager()
eventManager.Subscribe("testEvent", func(data interface{}) {
fmt.Println("Event happened:", data)
})
eventManager.Notify("testEvent", "testData")
ValidatorType
ValidatorType defines the protocol for a validation method. Implement this
to create custom validation methods for your integrity checks.
type ValidatorType interface
SHA1Validator
SHA1Validator is an implementation of the validation method using SHA-1
type SHA1Validator struct
SHA256Validator
SHA256Validator is an implementation of the validation method using SHA-256
type SHA256Validator struct
MD5Validator
MD5Validator is an implementation of the validation method using MD5
type MD5Validator struct
IntegrityCheckResult
IntegrityCheckResult represents the result of an integrity check
type IntegrityCheckResult struct
Fields
| Name | Type | Description |
|---|---|---|
| TotalRequested | int | |
| Passed | int | |
| Failed | int | |
| FailedChecks | []FailedCheck |
FailedCheck
FailedCheck represents a failed integrity check
type FailedCheck struct
Fields
| Name | Type | Description |
|---|---|---|
| ResourcePath | string | |
| RequestedHash | string | |
| DetectedHash | string |
CheckIntegrity
CheckIntegrity performs an integrity check of the provided data using the
provided validation method and returns the result. If a validation fails
the result will contain the failed checks.
The prefix parameter specifies the base path to be used for each file check.
Parameters
Returns
func CheckIntegrity(data []byte, method ValidatorType, prefix string) (IntegrityCheckResult, error)
{
pairings := make(map[string]string)
lines := strings.Split(string(data), "\n")
for _, line := range lines {
parts := strings.SplitN(line, " ", 2)
if len(parts) != 2 {
return IntegrityCheckResult{}, fmt.Errorf("invalid line format: %s", line)
}
pairings[parts[0]] = parts[1]
}
// Perform the integrity check using the provided validation method
return checkIntegrity(pairings, method, prefix)
}
Example
data := []byte("batman.txt 8c555f537cd1fe3f1239ebf7b6d639bc0d576bda\nrobin.txt 4e58c66d2ef2b9a60c7ea2bc03253d8b01874b52")
result, err := CheckIntegrity(data, SHA1Validator{}, "files/")
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Printf("Total requested: %d\n", result.TotalRequested)
fmt.Printf("Passed: %d\n", result.Passed)
fmt.Printf("Failed: %d\n", result.Failed)
for _, failedCheck := range result.FailedChecks {
fmt.Printf("Resource: %s\n", failedCheck.ResourcePath)
fmt.Printf("Requested: %s\n", failedCheck.RequestedHash)
fmt.Printf("Detected: %s\n", failedCheck.DetectedHash)
}
checkIntegrity
checkIntegrity performs the integrity check of the file data using
the provided validation method.
Parameters
Returns
func checkIntegrity(pairings map[string]string, method ValidatorType, prefix string) (IntegrityCheckResult, error)
{
var result IntegrityCheckResult
for resourcePath, requestedHash := range pairings {
// If a prefix is provided, we have to join it with the resource path to
// ensure the file is found in the place the developer expects.
fullPath := filepath.Join(prefix, resourcePath)
detectedHash, err := calculateHash(fullPath, method)
if err != nil {
fmt.Printf("Error calculating hash for %s: %v\n", fullPath, err)
continue
}
result.TotalRequested++
if requestedHash == detectedHash {
result.Passed++
} else {
result.Failed++
result.FailedChecks = append(result.FailedChecks, FailedCheck{
ResourcePath: fullPath,
RequestedHash: requestedHash,
DetectedHash: detectedHash,
})
}
}
return result, nil
}
calculateHash
calculateHash calculates the hash of a file using the provided validation
method and returns it as a string.
Parameters
Returns
func calculateHash(filePath string, method ValidatorType) (string, error)
{
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
return method.Hash(file)
}