-
Notifications
You must be signed in to change notification settings - Fork 0
/
tee_test.go
109 lines (88 loc) · 2.06 KB
/
tee_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package example
import (
"github.com/calvernaz/go-iterators"
"fmt"
"github.com/pkg/errors"
)
// This example shows how to use an iterator to implement the unix tee pipe.
func ExampleTee() {
// transform function
var tr iterator.TransformFunc = func(item interface{}) (interface{}, error) {
i, ok := item.(*MyItem)
if !ok {
return nil, errors.New("failed casting item to type *MyItem")
}
i.Name = i.Name + "Tr"
return i, nil
}
// slice of ints with an iterator
items := itemsArray(1, 10)
sliceIter := MyItemArray(items).Iterator()
// the tee iterator
iter := TeeIterator(sliceIter, tr)
// iterate over the transformed values
for iter.HasNext() {
trItem, err := iter.Next()
if err != nil {
return
}
fmt.Printf("%+v\n", trItem)
}
// Output:
// &{Id:1 Name:item_0001Tr}
// &{Id:2 Name:item_0002Tr}
// &{Id:3 Name:item_0003Tr}
// &{Id:4 Name:item_0004Tr}
// &{Id:5 Name:item_0005Tr}
// &{Id:6 Name:item_0006Tr}
// &{Id:7 Name:item_0007Tr}
// &{Id:8 Name:item_0008Tr}
// &{Id:9 Name:item_0009Tr}
// &{Id:10 Name:item_0010Tr}
}
type teeIterator struct {
iterator.Iterator
iterator.TransformFunc
}
func TeeIterator(iterator iterator.Iterator, fn iterator.TransformFunc) iterator.Iterator {
return &teeIterator{ iterator, fn }
}
func (t *teeIterator) Next() (next interface{}, e error) {
n, err := t.Iterator.Next()
if err != nil {
return nil, err
}
return t.TransformFunc(n)
}
// Helpers
//
type MyItem struct {
Id int
Name string
}
type MyItemArray []MyItem
func (a MyItemArray) Iterator() iterator.Iterator {
return iterator.NewDefaultIterator(next(a))
}
func next(items []MyItem) iterator.ComputeNext {
index := 0
return func() (interface{}, bool, error) {
if index >= len(items) {
return nil, true, nil
}
n := &items[index]
index++
return n, false, nil
}
}
// Adds the iterator behavior to a slice
func itemsArray(from int, to int) []MyItem {
var items []MyItem
for i := from; i <= to; i++ {
items = append(items, MyItem{
Id: i,
Name: fmt.Sprintf("item_%04d", i),
})
}
return items
}