| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 package cfgclient |
| 6 |
| 7 import ( |
| 8 "github.com/luci/luci-go/common/errors" |
| 9 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" |
| 10 ) |
| 11 |
| 12 // Resolver resolves configuration data into a native type. |
| 13 type Resolver interface { |
| 14 // Resolve resolves a single Item. |
| 15 Resolve(it *backend.Item) error |
| 16 } |
| 17 |
| 18 // MultiResolver resolves a slice of Item. |
| 19 // |
| 20 // If it resolves into a slice (which it should), it must preserve Item ordering |
| 21 // such that resolved Item "n" appears in the slice at index "n". |
| 22 // |
| 23 // Any individual resolution failures should be |
| 24 type MultiResolver interface { |
| 25 // PrepareMulti indicates that items are about to be loaded, as well as
the |
| 26 // number of resolved values. The MultiResolver should allocate and expo
rt its |
| 27 // output value. |
| 28 // |
| 29 // The value's contents will be populated in a series of successive |
| 30 // ResolveItemAt calls for indexes between zero and (size-1). |
| 31 PrepareMulti(size int) |
| 32 |
| 33 // ResolveItemAt resolves an individual item at the specified index. |
| 34 // PrepareMulti with a size greater than i must be called prior to using |
| 35 // ResolveItemAt. |
| 36 ResolveItemAt(i int, it *backend.Item) error |
| 37 } |
| 38 |
| 39 // FormattingResolver is a Resolver that changes the format of its contents. |
| 40 // If a Resolver does this, it self-describes the new format so that it can be |
| 41 // associated with the format later. |
| 42 type FormattingResolver interface { |
| 43 // Format returns the FormatterRegistry key and associated data for this |
| 44 // Resolver. |
| 45 // |
| 46 // An empty format represents no Formatter, meaning that this Resolver o
nly |
| 47 // supports the raw config service result. |
| 48 Format() backend.FormatSpec |
| 49 } |
| 50 |
| 51 func assertEmptyFormat(it *backend.Item) error { |
| 52 if !it.FormatSpec.Unformatted() { |
| 53 return errors.Reason("unknown format: %(format)q").D("format", i
t.FormatSpec.Formatter).Err() |
| 54 } |
| 55 return nil |
| 56 } |
| 57 |
| 58 // Bytes is a Resolver that resolves config data into a byte slice. |
| 59 func Bytes(out *[]byte) Resolver { return byteSliceResolver{out} } |
| 60 |
| 61 // BytesSlice is a MultiResolver that resolves condig data into a slice of byte |
| 62 // slices. |
| 63 func BytesSlice(out *[][]byte) MultiResolver { return multiByteSliceResolver{out
} } |
| 64 |
| 65 type byteSliceResolver struct { |
| 66 out *[]byte |
| 67 } |
| 68 |
| 69 func (r byteSliceResolver) Resolve(it *backend.Item) error { |
| 70 if err := assertEmptyFormat(it); err != nil { |
| 71 return err |
| 72 } |
| 73 *r.out = []byte(it.Content) |
| 74 return nil |
| 75 } |
| 76 |
| 77 type multiByteSliceResolver struct { |
| 78 out *[][]byte |
| 79 } |
| 80 |
| 81 func (r multiByteSliceResolver) PrepareMulti(size int) { |
| 82 switch size { |
| 83 case 0: |
| 84 *r.out = nil |
| 85 |
| 86 default: |
| 87 *r.out = make([][]byte, size) |
| 88 } |
| 89 } |
| 90 |
| 91 func (r multiByteSliceResolver) ResolveItemAt(i int, it *backend.Item) error { |
| 92 if err := assertEmptyFormat(it); err != nil { |
| 93 return err |
| 94 } |
| 95 (*r.out)[i] = []byte(it.Content) |
| 96 return nil |
| 97 } |
| 98 |
| 99 // String is a Resolver that resolves config data into a string. |
| 100 func String(out *string) Resolver { return stringResolver{out} } |
| 101 |
| 102 // StringSlice is a MultiResolver that resolves config data into a slice of |
| 103 // strings. |
| 104 func StringSlice(out *[]string) MultiResolver { return multiStringResolver{out}
} |
| 105 |
| 106 type stringResolver struct { |
| 107 out *string |
| 108 } |
| 109 |
| 110 func (r stringResolver) Resolve(it *backend.Item) error { |
| 111 if err := assertEmptyFormat(it); err != nil { |
| 112 return err |
| 113 } |
| 114 *r.out = it.Content |
| 115 return nil |
| 116 } |
| 117 |
| 118 type multiStringResolver struct { |
| 119 out *[]string |
| 120 } |
| 121 |
| 122 func (r multiStringResolver) PrepareMulti(size int) { |
| 123 switch size { |
| 124 case 0: |
| 125 *r.out = nil |
| 126 |
| 127 default: |
| 128 *r.out = make([]string, size) |
| 129 } |
| 130 } |
| 131 |
| 132 func (r multiStringResolver) ResolveItemAt(i int, it *backend.Item) error { |
| 133 if err := assertEmptyFormat(it); err != nil { |
| 134 return err |
| 135 } |
| 136 (*r.out)[i] = it.Content |
| 137 return nil |
| 138 } |
| OLD | NEW |