22package namer
33
44import (
5- "errors"
65 "fmt"
76 "iter"
87 "strings"
@@ -11,29 +10,66 @@ import (
1110const (
1211 hashName = "hash"
1312 signatureName = "sig"
14- keysPerName = 3
1513)
1614
17- var (
18- // ErrInvalidKey is returned when missing key, hash or signature.
19- ErrInvalidKey = errors .New ("missing key, hash or signature" )
20- // ErrInvalidInput is returned when input data is invalid.
21- ErrInvalidInput = errors .New ("failed to generate: invalid input data" )
22- // ErrInvalidPrefix is returned when prefix didn't match.
23- ErrInvalidPrefix = errors .New ("invalid prefix" )
24- )
15+ type InvalidKeyError struct {
16+ Key string
17+ Problem string
18+ }
19+
20+ func (e InvalidKeyError ) Error () string {
21+ return fmt .Sprintf ("invalid key '%s': %s" , e .Key , e .Problem )
22+ }
23+
24+ func errInvalidKey (key string , problem string ) error {
25+ return InvalidKeyError {
26+ Key : key ,
27+ Problem : problem ,
28+ }
29+ }
30+
31+ type InvalidNameError struct {
32+ Name string
33+ Problem string
34+ }
35+
36+ func (e InvalidNameError ) Error () string {
37+ return fmt .Sprintf ("invalid name '%s': %s" , e .Name , e .Problem )
38+ }
39+
40+ func errInvalidName (name string , problem string ) error {
41+ return InvalidNameError {
42+ Name : name ,
43+ Problem : problem ,
44+ }
45+ }
2546
2647// Results represents Namer working result.
2748type Results struct {
28- IsSingle bool // True if result contains only one object name.
29- IsSingleName string // Cached name when isSingle=true.
30- Result map [string ][]Key // Grouped keys: object name -> key list.
49+ isSingle bool // True if result contains only one object name.
50+ isSingleName string // Cached name when isSingle=true.
51+ result map [string ][]Key // Grouped keys: object name -> key list.
52+ }
53+
54+ func getFirstFromMap (m map [string ][]Key ) string {
55+ for name := range m {
56+ return name
57+ }
58+ return ""
59+ }
60+
61+ func NewResults (initial map [string ][]Key ) Results {
62+ return Results {
63+ isSingle : len (initial ) == 1 ,
64+ isSingleName : getFirstFromMap (initial ),
65+ result : initial ,
66+ }
3167}
3268
3369// SelectSingle gets keys for single-name case (if applicable).
3470func (r * Results ) SelectSingle () ([]Key , bool ) {
35- if r .IsSingle {
36- return r .Result [r .IsSingleName ], true
71+ if r .isSingle {
72+ return r .result [r .isSingleName ], true
3773 }
3874
3975 return nil , false
@@ -42,17 +78,21 @@ func (r *Results) SelectSingle() ([]Key, bool) {
4278// Items return iterator over all name->keys groups.
4379func (r * Results ) Items () iter.Seq2 [string , []Key ] {
4480 return func (yield func (str string , res []Key ) bool ) {
45- for i , v := range r .Result {
81+ for i , v := range r .result {
4682 if ! yield (i , v ) {
4783 return
4884 }
4985 }
5086 }
5187}
5288
89+ func (r * Results ) Result () map [string ][]Key {
90+ return r .result
91+ }
92+
5393// Select gets keys for a specific object name.
5494func (r * Results ) Select (name string ) ([]Key , bool ) {
55- if i , ok := r .Result [name ]; ok {
95+ if i , ok := r .result [name ]; ok {
5696 return i , true
5797 }
5898
@@ -61,7 +101,7 @@ func (r *Results) Select(name string) ([]Key, bool) {
61101
62102// Len returns the number of unique object names.
63103func (r * Results ) Len () int {
64- return len (r .Result )
104+ return len (r .result )
65105}
66106
67107// DefaultNamer represents default namer.
@@ -73,110 +113,138 @@ type DefaultNamer struct {
73113
74114// NewDefaultNamer returns new DefaultNamer object with hash/signature names configuration.
75115func NewDefaultNamer (prefix string , hashNames []string , sigNames []string ) * DefaultNamer {
76- prefix = strings .TrimPrefix (prefix , "/" )
77- prefix = strings .TrimSuffix (prefix , "/" )
78-
79116 return & DefaultNamer {
80- prefix : prefix , // "storage/".
81- hashNames : hashNames , // "sha256".
82- sigNames : sigNames , // "RSAPSS".
117+ prefix : strings . Trim ( prefix , "/" ),
118+ hashNames : hashNames ,
119+ sigNames : sigNames ,
83120 }
84121}
85122
86123// GenerateNames all keys for an object name.
87- func (n * DefaultNamer ) GenerateNames (name string ) []Key {
124+ func (n * DefaultNamer ) GenerateNames (name string ) ([]Key , error ) {
125+ switch {
126+ case name == "" :
127+ return nil , errInvalidName (name , "should not be empty" )
128+ case strings .HasSuffix (name , "/" ):
129+ return nil , errInvalidName (name , "should not be prefix" )
130+ }
131+
88132 name = strings .TrimPrefix (name , "/" )
89133
90134 out := make ([]Key , 0 , len (n .hashNames )+ len (n .sigNames )+ 1 )
91135
92136 out = append (out ,
93137 NewDefaultKey (
94- fmt . Sprintf ( "/%s/%s" , n . prefix , name ) ,
138+ name ,
95139 KeyTypeValue ,
96140 "" ,
97- [] byte {} ,
141+ fmt . Sprintf ( "/%s/%s" , n . prefix , name ) ,
98142 ))
99143
100144 for _ , hash := range n .hashNames {
101145 out = append (out ,
102146 NewDefaultKey (
103- fmt . Sprintf ( "/%s/%s/%s/%s" , n . prefix , hashName , hash , name ) ,
147+ name ,
104148 KeyTypeHash ,
105149 hash ,
106- [] byte {} ,
150+ fmt . Sprintf ( "/%s/%s/%s/%s" , n . prefix , hashName , hash , name ) ,
107151 ),
108152 )
109153 }
110154
111155 for _ , sig := range n .sigNames {
112156 out = append (out ,
113157 NewDefaultKey (
114- fmt . Sprintf ( "/%s/%s/%s/%s" , n . prefix , signatureName , sig , name ) ,
158+ name ,
115159 KeyTypeSignature ,
116160 sig ,
117- [] byte {} ,
161+ fmt . Sprintf ( "/%s/%s/%s/%s" , n . prefix , signatureName , sig , name ) ,
118162 ),
119163 )
120164 }
121165
122- return out
166+ return out , nil
123167}
124168
125- // ParseKeys combine multiple raw keys into grouped results.
126- func (n * DefaultNamer ) ParseKeys (names []string ) (Results , error ) {
127- var out Results
169+ func (n * DefaultNamer ) ParseKey (name string ) (DefaultKey , error ) {
170+ originalName := name
128171
129- out .Result = map [string ][]Key {}
130-
131- if len (names ) == 0 {
132- return out , ErrInvalidInput
133- }
134-
135- if len (names ) == 1 {
136- out .IsSingle = true
137- out .IsSingleName = names [0 ]
172+ name , found := strings .CutPrefix (strings .TrimPrefix (name , "/" ), n .prefix )
173+ if ! found {
174+ return DefaultKey {}, errInvalidKey (originalName , "prefix not found" )
138175 }
139176
140- for _ , name := range names {
141- originName := name
142-
143- name = strings .TrimPrefix (name , "/" )
144-
145- name , found := strings .CutPrefix (name , n .prefix )
146- if ! found {
147- return out , ErrInvalidInput
177+ name = strings .TrimPrefix (name , "/" )
178+ nameParts := strings .SplitN (name , "/" , 3 )
179+
180+ switch {
181+ case len (nameParts ) <= 0 || len (nameParts ) > 3 :
182+ panic ("illegal state" ) // Unreachable.
183+
184+ case nameParts [0 ] == signatureName :
185+ switch {
186+ case len (nameParts ) != 3 :
187+ return DefaultKey {}, errInvalidKey (originalName , "found sig prefix, but key name is incomplete" )
188+ case len (nameParts [1 ]) == 0 :
189+ return DefaultKey {}, errInvalidKey (originalName , "found sig prefix, but hash name is invalid" )
190+ case len (nameParts [2 ]) == 0 :
191+ return DefaultKey {}, errInvalidKey (originalName , "found sig prefix, but key name is invalid" )
192+ case strings .HasSuffix (nameParts [2 ], "/" ):
193+ return DefaultKey {}, errInvalidKey (originalName , "found hash prefix, but key name is prefix" )
148194 }
149195
150- name = strings .TrimSuffix (name , "/" )
196+ return NewDefaultKey (
197+ nameParts [2 ],
198+ KeyTypeSignature ,
199+ nameParts [1 ],
200+ originalName ,
201+ ), nil
202+ case nameParts [0 ] == hashName :
203+ switch {
204+ case len (nameParts ) != 3 :
205+ return DefaultKey {}, errInvalidKey (originalName , "found hash prefix, but key name is incomplete" )
206+ case len (nameParts [1 ]) == 0 :
207+ return DefaultKey {}, errInvalidKey (originalName , "found hash prefix, but hash name is invalid" )
208+ case len (nameParts [2 ]) == 0 :
209+ return DefaultKey {}, errInvalidKey (originalName , "found hash prefix, but key name is invalid" )
210+ case strings .HasSuffix (nameParts [2 ], "/" ):
211+ return DefaultKey {}, errInvalidKey (originalName , "found hash prefix, but key name is prefix" )
212+ }
151213
152- parts := strings .Split (name , "/" )
153- partslen := len (parts )
214+ return NewDefaultKey (
215+ nameParts [2 ],
216+ KeyTypeHash ,
217+ nameParts [1 ],
218+ originalName ,
219+ ), nil
220+ default :
221+ if strings .HasSuffix (name , "/" ) {
222+ return DefaultKey {}, errInvalidKey (originalName , "key name should not be prefix" )
223+ }
154224
155- var keyType KeyType
225+ return NewDefaultKey (
226+ name ,
227+ KeyTypeValue ,
228+ "" ,
229+ originalName ,
230+ ), nil
231+ }
232+ }
156233
157- var keyProp string
234+ // ParseKeys combine multiple raw keys into grouped results.
235+ func (n * DefaultNamer ) ParseKeys (names []string , ignoreError bool ) (Results , error ) {
236+ out := map [string ][]Key {}
158237
159- switch parts [0 ] {
160- case hashName :
161- keyType = KeyTypeHash
162- keyProp = parts [1 ]
163- case signatureName :
164- keyType = KeyTypeSignature
165- keyProp = parts [1 ]
166- default :
167- keyType = KeyTypeValue
168- keyProp = ""
238+ for _ , name := range names {
239+ key , err := n .ParseKey (name )
240+ switch {
241+ case err != nil && ignoreError :
242+ continue
243+ case err != nil :
244+ return Results {}, err
169245 }
170-
171- key := NewDefaultKey (
172- originName ,
173- keyType ,
174- keyProp ,
175- []byte {},
176- )
177-
178- out .Result [parts [partslen - 1 ]] = append (out .Result [parts [partslen - 1 ]], key )
246+ out [key .name ] = append (out [key .name ], key )
179247 }
180248
181- return out , nil
249+ return NewResults ( out ) , nil
182250}
0 commit comments