-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpair.go
More file actions
120 lines (103 loc) · 2.99 KB
/
pair.go
File metadata and controls
120 lines (103 loc) · 2.99 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
package iter
import (
"fmt"
"reflect"
)
// Pair represents a dyadic pair of values visited by a Walker. The root Pair
// will have no Parent() and it is permissible for a Pair to contain only a Key
// or Val. This means any of this interfaces types with nil zero values could be
// nil regardless if Err() is non-nil. The Err() field may be populated by the
// Walker or propagated from a user returned error.
//
// Caveats:
//
// Since channels do not have a sequential number to represent a location
// within a finite space a simple numeric counter relative to the first
// receive operation within the current block instead. This means that future
// calls to the same channel could return a identical sequence number.
//
// Example of elements:
//
// []int{1, 2} -> []Pair{ {0, 1}, {1, 2} }
// map[str]int{"a": 1, "b": 2} -> []Pair{ {"a", 1}, {"b", 2} }
//
// Structs:
//
// Key() will contain a reflect.StructFieldvalue, which may be anonymous or
// unexported.
// Val() will contain the associated fields current value.
//
// Slices, Arrays and Channels:
//
// Key() will contain a int type representing the elements location within the
// sequence.
// Val() will contain the element value located at Key().
//
// Maps:
//
// Key() will be a interface value of the maps key used to access the Val().
// Val() will be a interface value of the value located at Key().
//
type Pair interface {
// Err will return any error associated with the retrieval of this Pair.
Err() error
// Depth returns how many structured elements this Pair is nested within.
Depth() int
// Parent will return the parent Pair this Pair is associated to. For
// example if this Pair belongs to a map type, the parent would contain a
// Pair with Kind() reflect.Map and a reflect.Value of the map Value. If
// this is the top most element then it will have no Parent.
Parent() Pair
// Key will return the key associated with this value.
Key() interface{}
// Val will return the value associated with this key.
Val() interface{}
// Pair returns the key and value for this Pair.
Pair() (interface{}, interface{})
}
type pair struct {
key interface{}
val interface{}
pnt Pair
err error
}
// NewPair returns a new key-value pair to be used by Walkers.
func NewPair(parent Pair, key, value interface{}, err error) Pair {
return &pair{
key: key,
val: value,
pnt: parent,
err: err,
}
}
func (pr *pair) Err() error {
return pr.err
}
func (pr *pair) Depth() int {
if pr.pnt == nil {
return 0
}
return 1 + pr.pnt.Depth()
}
func (pr *pair) Parent() Pair {
return pr.pnt
}
func (pr *pair) Key() interface{} {
return pr.key
}
func (pr *pair) Val() interface{} {
return pr.val
}
func (pr *pair) Pair() (key, val interface{}) {
return pr.key, pr.val
}
func (pr *pair) String() string {
var k string
if v, ok := pr.key.(reflect.StructField); ok {
k = v.Name
} else {
k = fmt.Sprintf("%v", pr.key)
}
return fmt.Sprintf("Pair{(%T) %.12s => %.12s (%T)}",
pr.key, k, fmt.Sprintf("%v", pr.val), pr.val)
}