itererr.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright (C) 2025 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package itererr
  7. import "iter"
  8. // Collect returns a slice of the items from the iterator, plus the error if
  9. // any.
  10. func Collect[T any](it iter.Seq[T], errFn func() error) ([]T, error) {
  11. var s []T
  12. for v := range it {
  13. s = append(s, v)
  14. }
  15. return s, errFn()
  16. }
  17. // Zip interleaves the iterator value with the error. The iteration ends
  18. // after a non-nil error.
  19. func Zip[T any](it iter.Seq[T], errFn func() error) iter.Seq2[T, error] {
  20. return func(yield func(T, error) bool) {
  21. for v := range it {
  22. if !yield(v, nil) {
  23. break
  24. }
  25. }
  26. if err := errFn(); err != nil {
  27. var zero T
  28. yield(zero, err)
  29. }
  30. }
  31. }
  32. // Map returns a new iterator by applying the map function, while respecting
  33. // the error function. Additionally, the map function can return an error if
  34. // its own.
  35. func Map[A, B any](i iter.Seq[A], errFn func() error, mapFn func(A) (B, error)) (iter.Seq[B], func() error) {
  36. var retErr error
  37. return func(yield func(B) bool) {
  38. for v := range i {
  39. mapped, err := mapFn(v)
  40. if err != nil {
  41. retErr = err
  42. return
  43. }
  44. if !yield(mapped) {
  45. return
  46. }
  47. }
  48. }, func() error {
  49. if prevErr := errFn(); prevErr != nil {
  50. return prevErr
  51. }
  52. return retErr
  53. }
  54. }
  55. // Map returns a new iterator by applying the map function, while respecting
  56. // the error function. Additionally, the map function can return an error if
  57. // its own.
  58. func Map2[A, B, C any](i iter.Seq[A], errFn func() error, mapFn func(A) (B, C, error)) (iter.Seq2[B, C], func() error) {
  59. var retErr error
  60. return func(yield func(B, C) bool) {
  61. for v := range i {
  62. ma, mb, err := mapFn(v)
  63. if err != nil {
  64. retErr = err
  65. return
  66. }
  67. if !yield(ma, mb) {
  68. return
  69. }
  70. }
  71. }, func() error {
  72. if prevErr := errFn(); prevErr != nil {
  73. return prevErr
  74. }
  75. return retErr
  76. }
  77. }