Skip to content

Commit f6e531d

Browse files
authored
Merge pull request #4 from go-spring/develop
Develop
2 parents 7cf2c23 + 4d57765 commit f6e531d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3539
-4330
lines changed

conf/bind.go

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2024 The Go-Spring Authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import (
2424
"strings"
2525

2626
"github.com/go-spring/spring-core/util"
27-
"github.com/go-spring/spring-core/util/macro"
27+
"github.com/go-spring/spring-core/util/errutil"
2828
)
2929

3030
var (
@@ -94,22 +94,27 @@ type BindParam struct {
9494
}
9595

9696
func (param *BindParam) BindTag(tag string, validate reflect.StructTag) error {
97+
param.Validate = validate
9798
parsedTag, err := ParseTag(tag)
9899
if err != nil {
99100
return err
100101
}
102+
if parsedTag.Key == "" { // ${:=} 默认值语法
103+
if parsedTag.HasDef {
104+
param.Tag = parsedTag
105+
return nil
106+
}
107+
return fmt.Errorf("xxxx") // todo
108+
}
101109
if parsedTag.Key == "ROOT" {
102110
parsedTag.Key = ""
103-
} else if parsedTag.Key == "" {
104-
parsedTag.Key = "ANONYMOUS"
105111
}
106-
param.Tag = parsedTag
107112
if param.Key == "" {
108113
param.Key = parsedTag.Key
109114
} else if parsedTag.Key != "" {
110115
param.Key = param.Key + "." + parsedTag.Key
111116
}
112-
param.Validate = validate
117+
param.Tag = parsedTag
113118
return nil
114119
}
115120

@@ -118,11 +123,11 @@ type Filter interface {
118123
}
119124

120125
// BindValue binds properties to a value.
121-
func BindValue(p readOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) (RetErr error) {
126+
func BindValue(p ReadOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) (RetErr error) {
122127

123-
if !util.IsValueType(t) {
128+
if !util.IsPropBindingTarget(t) {
124129
err := errors.New("target should be value type")
125-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
130+
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
126131
}
127132

128133
defer func() {
@@ -144,29 +149,29 @@ func BindValue(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bind
144149
return bindSlice(p, v, t, param, filter)
145150
case reflect.Array:
146151
err := errors.New("use slice instead of array")
147-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
152+
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
148153
default: // for linter
149154
}
150155

151156
fn := converters[t]
152157
if fn == nil && v.Kind() == reflect.Struct {
153158
if err := bindStruct(p, v, t, param, filter); err != nil {
154-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
159+
return err // no wrap
155160
}
156161
return nil
157162
}
158163

159164
val, err := resolve(p, param)
160165
if err != nil {
161-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
166+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
162167
}
163168

164169
if fn != nil {
165170
fnValue := reflect.ValueOf(fn)
166171
out := fnValue.Call([]reflect.Value{reflect.ValueOf(val)})
167172
if !out[1].IsNil() {
168173
err = out[1].Interface().(error)
169-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
174+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
170175
}
171176
v.Set(out[0])
172177
return nil
@@ -179,45 +184,45 @@ func BindValue(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bind
179184
v.SetUint(u)
180185
return nil
181186
}
182-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
187+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
183188
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
184189
var i int64
185190
if i, err = strconv.ParseInt(val, 0, 0); err == nil {
186191
v.SetInt(i)
187192
return nil
188193
}
189-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
194+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
190195
case reflect.Float32, reflect.Float64:
191196
var f float64
192197
if f, err = strconv.ParseFloat(val, 64); err == nil {
193198
v.SetFloat(f)
194199
return nil
195200
}
196-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
201+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
197202
case reflect.Bool:
198203
var b bool
199204
if b, err = strconv.ParseBool(val); err == nil {
200205
v.SetBool(b)
201206
return nil
202207
}
203-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
208+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
204209
case reflect.String:
205210
v.SetString(val)
206211
return nil
207212
default: // for linter
208213
}
209214

210-
err = fmt.Errorf("unsupported bind type %q", t.String())
211-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
215+
err = errors.New("unsupported bind type")
216+
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
212217
}
213218

214219
// bindSlice binds properties to a slice value.
215-
func bindSlice(p readOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
220+
func bindSlice(p ReadOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
216221

217222
et := t.Elem()
218223
p, err := getSlice(p, et, param)
219224
if err != nil {
220-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
225+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
221226
}
222227

223228
slice := reflect.MakeSlice(t, 0, 0)
@@ -238,14 +243,14 @@ func bindSlice(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bind
238243
break
239244
}
240245
if err != nil {
241-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
246+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
242247
}
243248
slice = reflect.Append(slice, e)
244249
}
245250
return nil
246251
}
247252

248-
func getSlice(p readOnlyProperties, et reflect.Type, param BindParam) (readOnlyProperties, error) {
253+
func getSlice(p ReadOnlyProperties, et reflect.Type, param BindParam) (ReadOnlyProperties, error) {
249254

250255
// properties that defined as list.
251256
if p.Has(param.Key + "[0]") {
@@ -259,13 +264,13 @@ func getSlice(p readOnlyProperties, et reflect.Type, param BindParam) (readOnlyP
259264
strVal = p.Get(param.Key)
260265
} else {
261266
if !param.Tag.HasDef {
262-
return nil, fmt.Errorf("%s: property %q %w", macro.FileLine(), param.Key, ErrNotExist)
267+
return nil, fmt.Errorf("property %q %w", param.Key, ErrNotExist)
263268
}
264269
if param.Tag.Def == "" {
265270
return nil, nil
266271
}
267272
if !util.IsPrimitiveValueType(et) && converters[et] == nil {
268-
return nil, fmt.Errorf("%s: can't find converter for %s", macro.FileLine(), et.String())
273+
return nil, fmt.Errorf("can't find converter for %s", et.String())
269274
}
270275
strVal = param.Tag.Def
271276
}
@@ -286,35 +291,44 @@ func getSlice(p readOnlyProperties, et reflect.Type, param BindParam) (readOnlyP
286291
}
287292
} else if fn, ok := splitters[s]; ok && fn != nil {
288293
if arrVal, err = fn(strVal); err != nil {
289-
return nil, fmt.Errorf("%s: split error: %w, value: %q", macro.FileLine(), err, strVal)
294+
return nil, fmt.Errorf("split error: %w, value: %q", err, strVal)
290295
}
291296
} else {
292-
return nil, fmt.Errorf("%s: unknown splitter %q", macro.FileLine(), s)
297+
return nil, fmt.Errorf("unknown splitter %q", s)
293298
}
294299

295300
r := New()
296301
for i, s := range arrVal {
297302
k := fmt.Sprintf("%s[%d]", param.Key, i)
298-
_ = r.storage.Set(k, s)
303+
if err = r.storage.Set(k, s); err != nil {
304+
return nil, err
305+
}
299306
}
300307
return r, nil
301308
}
302309

303310
// bindMap binds properties to a map value.
304-
func bindMap(p readOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
311+
func bindMap(p ReadOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
305312

306313
if param.Tag.HasDef && param.Tag.Def != "" {
307314
err := errors.New("map can't have a non-empty default value")
308-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
315+
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
309316
}
310317

311318
et := t.Elem()
312319
ret := reflect.MakeMap(t)
313320
defer func() { v.Set(ret) }()
314321

322+
// 当成默认值处理
323+
if param.Tag.Key == "" {
324+
if param.Tag.HasDef {
325+
return nil
326+
}
327+
}
328+
315329
keys, err := p.SubKeys(param.Key)
316330
if err != nil {
317-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
331+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
318332
}
319333

320334
for _, key := range keys {
@@ -327,21 +341,20 @@ func bindMap(p readOnlyProperties, v reflect.Value, t reflect.Type, param BindPa
327341
Key: subKey,
328342
Path: param.Path,
329343
}
330-
err = BindValue(p, e, et, subParam, filter)
331-
if err != nil {
332-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
344+
if err = BindValue(p, e, et, subParam, filter); err != nil {
345+
return err // no wrap
333346
}
334347
ret.SetMapIndex(reflect.ValueOf(key), e)
335348
}
336349
return nil
337350
}
338351

339352
// bindStruct binds properties to a struct value.
340-
func bindStruct(p readOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
353+
func bindStruct(p ReadOnlyProperties, v reflect.Value, t reflect.Type, param BindParam, filter Filter) error {
341354

342355
if param.Tag.HasDef && param.Tag.Def != "" {
343356
err := errors.New("struct can't have a non-empty default value")
344-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
357+
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
345358
}
346359

347360
for i := 0; i < t.NumField(); i++ {
@@ -359,7 +372,7 @@ func bindStruct(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bin
359372

360373
if tag, ok := ft.Tag.Lookup("value"); ok {
361374
if err := subParam.BindTag(tag, ft.Tag); err != nil {
362-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
375+
return errutil.WrapError(err, "bind path=%s type=%s error", param.Path, v.Type().String())
363376
}
364377
if filter != nil {
365378
ret, err := filter.Do(fv.Addr().Interface(), subParam)
@@ -371,7 +384,7 @@ func bindStruct(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bin
371384
}
372385
}
373386
if err := BindValue(p, fv, ft.Type, subParam, filter); err != nil {
374-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
387+
return err // no wrap
375388
}
376389
continue
377390
}
@@ -382,12 +395,12 @@ func bindStruct(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bin
382395
continue
383396
}
384397
if err := bindStruct(p, fv, ft.Type, subParam, filter); err != nil {
385-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
398+
return err // no wrap
386399
}
387400
continue
388401
}
389402

390-
if util.IsValueType(ft.Type) {
403+
if util.IsPropBindingTarget(ft.Type) {
391404
if subParam.Key == "" {
392405
subParam.Key = ft.Name
393406
} else {
@@ -396,33 +409,31 @@ func bindStruct(p readOnlyProperties, v reflect.Value, t reflect.Type, param Bin
396409
subParam.Key = strings.ToLower(subParam.Key)
397410
subParam.Key = strings.ReplaceAll(subParam.Key, "_", ".")
398411
if err := BindValue(p, fv, ft.Type, subParam, filter); err != nil {
399-
return fmt.Errorf("%s: bind %s error, %w", macro.FileLine(), param.Path, err)
412+
return err // no wrap
400413
}
401414
}
402415
}
403416
return nil
404417
}
405418

406419
// resolve returns property references processed property value.
407-
func resolve(p readOnlyProperties, param BindParam) (string, error) {
420+
func resolve(p ReadOnlyProperties, param BindParam) (string, error) {
408421
const defVal = "@@def@@"
409-
val := p.Get(param.Key, Def(defVal))
422+
val := p.Get(param.Key, defVal)
410423
if val != defVal {
411424
return resolveString(p, val)
412425
}
413426
if p.Has(param.Key) {
414-
err := fmt.Errorf("property %q isn't simple value", param.Key)
415-
return "", fmt.Errorf("%s: resolve property %q error, %w", macro.FileLine(), param.Key, err)
427+
return "", fmt.Errorf("property key=%s isn't simple value", param.Key)
416428
}
417429
if param.Tag.HasDef {
418430
return resolveString(p, param.Tag.Def)
419431
}
420-
err := fmt.Errorf("property %q %w", param.Key, ErrNotExist)
421-
return "", fmt.Errorf("%s: resolve property %q error, %w", macro.FileLine(), param.Key, err)
432+
return "", fmt.Errorf("property key=%s %w", param.Key, ErrNotExist)
422433
}
423434

424435
// resolveString returns property references processed string.
425-
func resolveString(p readOnlyProperties, s string) (string, error) {
436+
func resolveString(p ReadOnlyProperties, s string) (string, error) {
426437

427438
var (
428439
length = len(s)
@@ -456,20 +467,20 @@ func resolveString(p readOnlyProperties, s string) (string, error) {
456467

457468
if end < 0 || count > 0 {
458469
err := ErrInvalidSyntax
459-
return "", fmt.Errorf("%s: resolve string %q error, %w", macro.FileLine(), s, err)
470+
return "", fmt.Errorf("resolve string %q error: %w", s, err)
460471
}
461472

462473
var param BindParam
463474
_ = param.BindTag(s[start:end+1], "")
464475

465476
s1, err := resolve(p, param)
466477
if err != nil {
467-
return "", fmt.Errorf("%s: resolve string %q error, %w", macro.FileLine(), s, err)
478+
return "", errutil.WrapError(err, "resolve string %q error", s)
468479
}
469480

470481
s2, err := resolveString(p, s[end+1:])
471482
if err != nil {
472-
return "", fmt.Errorf("%s: resolve string %q error, %w", macro.FileLine(), s, err)
483+
return "", errutil.WrapError(err, "resolve string %q error", s)
473484
}
474485

475486
return s[:start] + s1 + s2, nil

0 commit comments

Comments
 (0)