-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathvalidator.go
74 lines (63 loc) · 1.99 KB
/
validator.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
package record
import (
"errors"
"fmt"
)
// ErrInvalidRecordType is returned if a DHTRecord keys prefix
// is not found in the Validator map of the DHT.
var ErrInvalidRecordType = errors.New("invalid record keytype")
// ErrBetterRecord is returned by a subsystem when it fails because it found a
// better record.
type ErrBetterRecord struct {
// Key is the key associated with the record.
Key string
// Value is the best value that was found, according to the record's
// validator.
Value []byte
}
func (e *ErrBetterRecord) Error() string {
return fmt.Sprintf("found better value for %q", e.Key)
}
// Validator is an interface that should be implemented by record validators.
type Validator interface {
// Validate validates the given record, returning an error if it's
// invalid (e.g., expired, signed by the wrong key, etc.).
Validate(key string, value []byte) error
// Select selects the best record from the set of records (e.g., the
// newest).
//
// Decisions made by select should be stable.
Select(key string, values [][]byte) (int, error)
}
// NamespacedValidator is a validator that delegates to sub-validators by
// namespace.
type NamespacedValidator map[string]Validator
// ValidatorByKey looks up the validator responsible for validating the given
// key.
func (v NamespacedValidator) ValidatorByKey(key string) Validator {
ns, _, err := SplitKey(key)
if err != nil {
return nil
}
return v[ns]
}
// Validate conforms to the Validator interface.
func (v NamespacedValidator) Validate(key string, value []byte) error {
vi := v.ValidatorByKey(key)
if vi == nil {
return ErrInvalidRecordType
}
return vi.Validate(key, value)
}
// Select conforms to the Validator interface.
func (v NamespacedValidator) Select(key string, values [][]byte) (int, error) {
if len(values) == 0 {
return 0, errors.New("can't select from no values")
}
vi := v.ValidatorByKey(key)
if vi == nil {
return 0, ErrInvalidRecordType
}
return vi.Select(key, values)
}
var _ Validator = NamespacedValidator{}