-
Notifications
You must be signed in to change notification settings - Fork 3.5k
/
string.go
81 lines (66 loc) · 1.71 KB
/
string.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
package cursors
// StringIterator describes the behavior for enumerating a sequence of
// string values.
type StringIterator interface {
// Next advances the StringIterator to the next value. It returns false
// when there are no more values.
Next() bool
// Value returns the current value.
Value() string
Stats() CursorStats
}
// EmptyStringIterator is an implementation of StringIterator that returns
// no values.
var EmptyStringIterator StringIterator = &stringIterator{}
type stringIterator struct{}
func (*stringIterator) Next() bool { return false }
func (*stringIterator) Value() string { return "" }
func (*stringIterator) Stats() CursorStats { return CursorStats{} }
type StringSliceIterator struct {
s []string
v string
i int
stats CursorStats
}
func NewStringSliceIterator(s []string) *StringSliceIterator {
return &StringSliceIterator{s: s, i: 0}
}
func NewStringSliceIteratorWithStats(s []string, stats CursorStats) *StringSliceIterator {
return &StringSliceIterator{s: s, i: 0, stats: stats}
}
func (s *StringSliceIterator) Next() bool {
if s.i < len(s.s) {
s.v = s.s[s.i]
s.i++
return true
}
s.v = ""
return false
}
func (s *StringSliceIterator) Value() string {
return s.v
}
func (s *StringSliceIterator) Stats() CursorStats {
return s.stats
}
func (s *StringSliceIterator) toSlice() []string {
if s.i < len(s.s) {
return s.s[s.i:]
}
return nil
}
// StringIteratorToSlice reads the remainder of i into a slice and
// returns the result.
func StringIteratorToSlice(i StringIterator) []string {
if i == nil {
return nil
}
if si, ok := i.(*StringSliceIterator); ok {
return si.toSlice()
}
var a []string
for i.Next() {
a = append(a, i.Value())
}
return a
}