pre_go20.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //go:build !go1.20
  2. package uri
  3. import (
  4. "errors"
  5. "fmt"
  6. )
  7. // TODO: build tag should be go1.20
  8. var _ Error = &uriErr{}
  9. type uriErr struct {
  10. err error
  11. wrapped error
  12. }
  13. func (e uriErr) Unwrap() error {
  14. return e.wrapped
  15. }
  16. func (e *uriErr) Is(target error) bool {
  17. return e == target || errors.Is(e.err, target) || errors.Is(e.wrapped, target)
  18. }
  19. func (e uriErr) Error() string {
  20. if e.wrapped != nil {
  21. return fmt.Sprintf("%v: %v", e.err, e.wrapped)
  22. }
  23. if e.err != nil {
  24. return e.err.Error()
  25. }
  26. return ""
  27. }
  28. // newErr emulates a wrappable error available with go1.20 standard library.
  29. func newErr(msg string) error {
  30. return &uriErr{
  31. err: fmt.Errorf(msg),
  32. }
  33. }
  34. // errorsJoin emulates the error wrapping carried out with go1.20 errors standard library.
  35. func errorsJoin(errs ...error) error {
  36. if len(errs) == 0 {
  37. return nil
  38. }
  39. wrappedErr := &uriErr{err: errs[0]}
  40. current := wrappedErr
  41. for _, err := range errs[1:] {
  42. if err == nil {
  43. continue
  44. }
  45. w := &uriErr{err: err}
  46. current.wrapped = w
  47. current = w
  48. }
  49. return wrappedErr
  50. }