iterator.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package iter
  2. import "github.com/anacrolix/missinggo/slices"
  3. type Iterator interface {
  4. // Advances to the next value. Returns false if there are no more values.
  5. // Must be called before the first value.
  6. Next() bool
  7. // Returns the current value. Should panic when the iterator is in an
  8. // invalid state.
  9. Value() interface{}
  10. // Ceases iteration prematurely. This should occur implicitly if Next
  11. // returns false.
  12. Stop()
  13. }
  14. func ToFunc(it Iterator) Func {
  15. return func(cb Callback) {
  16. defer it.Stop()
  17. for it.Next() {
  18. if !cb(it.Value()) {
  19. break
  20. }
  21. }
  22. }
  23. }
  24. type sliceIterator struct {
  25. slice []interface{}
  26. value interface{}
  27. ok bool
  28. }
  29. func (me *sliceIterator) Next() bool {
  30. if len(me.slice) == 0 {
  31. return false
  32. }
  33. me.value = me.slice[0]
  34. me.slice = me.slice[1:]
  35. me.ok = true
  36. return true
  37. }
  38. func (me *sliceIterator) Value() interface{} {
  39. if !me.ok {
  40. panic("no value; call Next")
  41. }
  42. return me.value
  43. }
  44. func (me *sliceIterator) Stop() {}
  45. func Slice(a []interface{}) Iterator {
  46. return &sliceIterator{
  47. slice: a,
  48. }
  49. }
  50. func StringIterator(a string) Iterator {
  51. return Slice(slices.ToEmptyInterface(a))
  52. }
  53. func ToSlice(f Func) (ret []interface{}) {
  54. f(func(v interface{}) bool {
  55. ret = append(ret, v)
  56. return true
  57. })
  58. return
  59. }