diff options
author | 2021-11-13 12:29:08 +0100 | |
---|---|---|
committer | 2021-11-13 12:29:08 +0100 | |
commit | 829a934d23ab221049b4d54926305d8d5d64c9ad (patch) | |
tree | f4e382b289c113d3ba8a3c7a183507a5609c46c0 /vendor/codeberg.org/gruf/go-errors | |
parent | smtp + email confirmation (#285) (diff) | |
download | gotosocial-829a934d23ab221049b4d54926305d8d5d64c9ad.tar.xz |
update dependencies (#296)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-errors')
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/LICENSE | 9 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/README.md | 1 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/data.go | 74 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/errors.go | 180 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/once.go | 45 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/std.go | 18 |
6 files changed, 327 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-errors/LICENSE b/vendor/codeberg.org/gruf/go-errors/LICENSE new file mode 100644 index 000000000..b7c4417ac --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2021 gruf + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/codeberg.org/gruf/go-errors/README.md b/vendor/codeberg.org/gruf/go-errors/README.md new file mode 100644 index 000000000..7e9ffbd9c --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/README.md @@ -0,0 +1 @@ +simple but powerful errors library that allows providing context information with errors
\ No newline at end of file diff --git a/vendor/codeberg.org/gruf/go-errors/data.go b/vendor/codeberg.org/gruf/go-errors/data.go new file mode 100644 index 000000000..3a32fd69e --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/data.go @@ -0,0 +1,74 @@ +package errors + +import ( + "sync" + + "codeberg.org/gruf/go-bytes" + "codeberg.org/gruf/go-logger" +) + +// global logfmt data formatter +var logfmt = logger.TextFormat{Strict: false} + +// KV is a structure for setting key-value pairs in ErrorData +type KV struct { + Key string + Value interface{} +} + +// ErrorData defines a way to set and access contextual error data. +// The default implementation of this is thread-safe +type ErrorData interface { + // Value will attempt to fetch value for given key in ErrorData + Value(string) (interface{}, bool) + + // Append adds the supplied key-values to ErrorData, similar keys DO overwrite + Append(...KV) + + // String returns a string representation of the ErrorData + String() string +} + +// NewData returns a new ErrorData implementation +func NewData() ErrorData { + return &errorData{ + data: make(map[string]interface{}, 10), + } +} + +// errorData is our ErrorData implementation, this is essentially +// just a thread-safe string-interface map implementation +type errorData struct { + data map[string]interface{} + buf bytes.Buffer + mu sync.Mutex +} + +func (d *errorData) Value(key string) (interface{}, bool) { + d.mu.Lock() + v, ok := d.data[key] + d.mu.Unlock() + return v, ok +} + +func (d *errorData) Append(kvs ...KV) { + d.mu.Lock() + for i := range kvs { + k := kvs[i].Key + v := kvs[i].Value + d.data[k] = v + } + d.mu.Unlock() +} + +func (d *errorData) String() string { + d.mu.Lock() + + d.buf.Reset() + d.buf.B = append(d.buf.B, '{') + logfmt.AppendFields(&d.buf, d.data) + d.buf.B = append(d.buf.B, '}') + + d.mu.Unlock() + return d.buf.StringPtr() +} diff --git a/vendor/codeberg.org/gruf/go-errors/errors.go b/vendor/codeberg.org/gruf/go-errors/errors.go new file mode 100644 index 000000000..283bdb098 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/errors.go @@ -0,0 +1,180 @@ +package errors + +import "fmt" + +// ErrorContext defines a wrappable error with the ability to hold extra contextual information +type ErrorContext interface { + // implement base error interface + error + + // Is identifies whether the receiver contains / is the target + Is(error) bool + + // Unwrap reveals the underlying wrapped error (if any!) + Unwrap() error + + // Value attempts to fetch contextual data for given key from this ErrorContext + Value(string) (interface{}, bool) + + // Append allows adding contextual data to this ErrorContext + Append(...KV) ErrorContext + + // Data returns the contextual data structure associated with this ErrorContext + Data() ErrorData +} + +// New returns a new ErrorContext created from string +func New(msg string) ErrorContext { + return stringError(msg) +} + +// Newf returns a new ErrorContext created from format string +func Newf(s string, a ...interface{}) ErrorContext { + return stringError(fmt.Sprintf(s, a...)) +} + +// Wrap ensures supplied error is an ErrorContext, wrapping if necessary +func Wrap(err error) ErrorContext { + // Nil error, do nothing + if err == nil { + return nil + } + + // Check if this is already wrapped somewhere in stack + if xerr, ok := err.(*errorContext); ok { + return xerr + } else if As(err, &xerr) { + // This is really not an ideal situation, + // but we try to make do by salvaging the + // contextual error data from earlier in + // stack, setting current error to the top + // and setting the unwrapped error to inner + return &errorContext{ + data: xerr.data, + innr: Unwrap(err), + err: err, + } + } + + // Return new Error type + return &errorContext{ + data: NewData(), + innr: nil, + err: err, + } +} + +// WrapMsg wraps supplied error as inner, returning an ErrorContext +// with a new outer error made from the supplied message string +func WrapMsg(err error, msg string) ErrorContext { + // Nil error, do nothing + if err == nil { + return nil + } + + // Check if this is already wrapped + var xerr *errorContext + if As(err, &xerr) { + return &errorContext{ + data: xerr.data, + innr: err, + err: New(msg), + } + } + + // Return new wrapped error + return &errorContext{ + data: NewData(), + innr: err, + err: stringError(msg), + } +} + +// WrapMsgf wraps supplied error as inner, returning an ErrorContext with +// a new outer error made from the supplied message format string +func WrapMsgf(err error, msg string, a ...interface{}) ErrorContext { + return WrapMsg(err, fmt.Sprintf(msg, a...)) +} + +// ErrorData attempts fetch ErrorData from supplied error, returns nil otherwise +func Data(err error) ErrorData { + x, ok := err.(ErrorContext) + if ok { + return x.Data() + } + return nil +} + +// stringError is the simplest ErrorContext implementation +type stringError string + +func (e stringError) Error() string { + return string(e) +} + +func (e stringError) Is(err error) bool { + se, ok := err.(stringError) + return ok && e == se +} + +func (e stringError) Unwrap() error { + return nil +} + +func (e stringError) Value(key string) (interface{}, bool) { + return nil, false +} + +func (e stringError) Append(kvs ...KV) ErrorContext { + data := NewData() + data.Append(kvs...) + return &errorContext{ + data: data, + innr: nil, + err: e, + } +} + +func (e stringError) Data() ErrorData { + return nil +} + +// errorContext is the *actual* ErrorContext implementation +type errorContext struct { + // data contains any appended context data, there will only ever be one + // instance of data within an ErrorContext stack + data ErrorData + + // innr is the inner wrapped error in this structure, it is only accessible + // via .Unwrap() or via .Is() + innr error + + // err is the top-level error in this wrapping structure, we identify + // as this error type via .Is() and return its error message + err error +} + +func (e *errorContext) Error() string { + return e.err.Error() +} + +func (e *errorContext) Is(err error) bool { + return Is(e.err, err) || Is(e.innr, err) +} + +func (e *errorContext) Unwrap() error { + return e.innr +} + +func (e *errorContext) Value(key string) (interface{}, bool) { + return e.data.Value(key) +} + +func (e *errorContext) Append(kvs ...KV) ErrorContext { + e.data.Append(kvs...) + return e +} + +func (e *errorContext) Data() ErrorData { + return e.data +} diff --git a/vendor/codeberg.org/gruf/go-errors/once.go b/vendor/codeberg.org/gruf/go-errors/once.go new file mode 100644 index 000000000..ba21ed695 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/once.go @@ -0,0 +1,45 @@ +package errors + +import ( + "sync/atomic" + "unsafe" +) + +// OnceError is an error structure that supports safe multi-threaded +// usage and setting only once (until reset) +type OnceError struct { + err unsafe.Pointer +} + +// NewOnce returns a new OnceError instance +func NewOnce() OnceError { + return OnceError{ + err: nil, + } +} + +func (e *OnceError) Store(err error) { + // Nothing to do + if err == nil { + return + } + + // Only set if not already + atomic.CompareAndSwapPointer( + &e.err, + nil, + unsafe.Pointer(&err), + ) +} + +func (e *OnceError) Load() error { + return *(*error)(atomic.LoadPointer(&e.err)) +} + +func (e *OnceError) IsSet() bool { + return (atomic.LoadPointer(&e.err) != nil) +} + +func (e *OnceError) Reset() { + atomic.StorePointer(&e.err, nil) +} diff --git a/vendor/codeberg.org/gruf/go-errors/std.go b/vendor/codeberg.org/gruf/go-errors/std.go new file mode 100644 index 000000000..2e4e9a0c4 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/std.go @@ -0,0 +1,18 @@ +package errors + +import "errors" + +// Is wraps "errors".Is() +func Is(err, target error) bool { + return errors.Is(err, target) +} + +// As wraps "errors".As() +func As(err error, target interface{}) bool { + return errors.As(err, target) +} + +// Unwrap wraps "errors".Unwrap() +func Unwrap(err error) error { + return errors.Unwrap(err) +} |