mirror of
https://codeberg.org/readeck/readeck.git
synced 2026-06-18 11:04:36 +00:00
89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
// SPDX-FileCopyrightText: © 2026 Olivier Meunier <olivier@neokraft.net>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package forms
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"iter"
|
|
"strings"
|
|
)
|
|
|
|
// Errors is an error list.
|
|
type Errors []error
|
|
|
|
func (e Errors) Error() string {
|
|
return e.String()
|
|
}
|
|
|
|
func (e Errors) String() string {
|
|
if len(e) == 0 {
|
|
return ""
|
|
}
|
|
|
|
res := make([]string, len(e))
|
|
for i, x := range e {
|
|
res[i] = x.Error()
|
|
}
|
|
return strings.Join(res, ", ")
|
|
}
|
|
|
|
// MarshalJSON implements [json.Marshaler].
|
|
func (e Errors) MarshalJSON() ([]byte, error) {
|
|
if len(e) == 0 {
|
|
return json.Marshal(nil)
|
|
}
|
|
|
|
res := make([]string, len(e))
|
|
for i := range e {
|
|
res[i] = e[i].Error()
|
|
}
|
|
|
|
return json.Marshal(res)
|
|
}
|
|
|
|
func (e Errors) Unwrap() []error {
|
|
return e
|
|
}
|
|
|
|
// IterErrors returns an iterator over an error and flatens the result.
|
|
// It recursively yields errors contained in the error when it implements
|
|
// Unwrap() []error (like [errors.Join] or [Errors] do).
|
|
// Every result is wrapped in a [localizedError] so its call to Error()
|
|
// produces a translated error.
|
|
func IterErrors(err error) iter.Seq[error] {
|
|
return func(yield func(error) bool) {
|
|
if !pushErrors(err, yield) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// IterErrorsTr returns an iterator that yields errors wrapped as
|
|
// localized error so they can be translated when calling their
|
|
// Error() method.
|
|
func IterErrorsTr(ctx context.Context, err error) iter.Seq[error] {
|
|
return func(yield func(error) bool) {
|
|
for err := range IterErrors(err) {
|
|
if !yield(WrapTrError(ctx, err)) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func pushErrors(err error, yield func(error) bool) bool {
|
|
if err, ok := err.(interface{ Unwrap() []error }); ok {
|
|
for _, err := range err.Unwrap() {
|
|
if !pushErrors(err, yield) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
return yield(err)
|
|
}
|