Skip to content

Commit c9231e2

Browse files
authored
Merge pull request #19 from lvan100/main
Add README.md for Bookman and Startup projects
2 parents 29cf144 + d161eb1 commit c9231e2

Some content is hidden

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

49 files changed

+631
-554
lines changed

conf/bind.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (param *BindParam) BindTag(tag string, validate reflect.StructTag) error {
124124

125125
// Filter defines an interface for filtering configuration fields during binding.
126126
type Filter interface {
127-
Do(i interface{}, param BindParam) (bool, error)
127+
Do(i any, param BindParam) (bool, error)
128128
}
129129

130130
// BindValue binds a value from properties `p` to the reflect.Value `v` of type `t`
@@ -366,7 +366,7 @@ func bindStruct(p Properties, v reflect.Value, t reflect.Type, param BindParam,
366366
return fmt.Errorf("bind path=%s type=%s error: %w", param.Path, v.Type().String(), err)
367367
}
368368

369-
for i := 0; i < t.NumField(); i++ {
369+
for i := range t.NumField() {
370370
ft := t.Field(i)
371371
fv := v.Field(i)
372372

conf/bind_test.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ func init() {
3535
conf.RegisterSplitter("PointSplitter", PointSplitter)
3636
}
3737

38-
type funcFilter func(i interface{}, param conf.BindParam) (bool, error)
38+
type funcFilter func(i any, param conf.BindParam) (bool, error)
3939

40-
func (f funcFilter) Do(i interface{}, param conf.BindParam) (bool, error) {
40+
func (f funcFilter) Do(i any, param conf.BindParam) (bool, error) {
4141
return f(i, param)
4242
}
4343

@@ -77,7 +77,7 @@ func TestConverter(t *testing.T) {
7777
})
7878

7979
t.Run("error", func(t *testing.T) {
80-
p := conf.Map(map[string]interface{}{
80+
p := conf.Map(map[string]any{
8181
"time": "2025-02-01M00:00:00",
8282
})
8383
err := p.Bind(&s)
@@ -304,7 +304,7 @@ func TestProperties_Bind(t *testing.T) {
304304
var s struct {
305305
Value int `value:"${v}" expr:"$>9"`
306306
}
307-
err := conf.Map(map[string]interface{}{
307+
err := conf.Map(map[string]any{
308308
"v": "1",
309309
}).Bind(&s)
310310
assert.ThatError(t, err).Matches("validate failed on .* for value 1")
@@ -321,7 +321,7 @@ func TestProperties_Bind(t *testing.T) {
321321
var s struct {
322322
Value int `value:"${v}"`
323323
}
324-
err := conf.Map(map[string]interface{}{
324+
err := conf.Map(map[string]any{
325325
"v": "abc",
326326
}).Bind(&s)
327327
assert.ThatError(t, err).Matches("strconv.ParseInt: parsing .*: invalid syntax")
@@ -331,7 +331,7 @@ func TestProperties_Bind(t *testing.T) {
331331
var s struct {
332332
Value uint `value:"${v}"`
333333
}
334-
err := conf.Map(map[string]interface{}{
334+
err := conf.Map(map[string]any{
335335
"v": "abc",
336336
}).Bind(&s)
337337
assert.ThatError(t, err).Matches("strconv.ParseUint: parsing .*: invalid syntax")
@@ -341,7 +341,7 @@ func TestProperties_Bind(t *testing.T) {
341341
var s struct {
342342
Value float32 `value:"${v}"`
343343
}
344-
err := conf.Map(map[string]interface{}{
344+
err := conf.Map(map[string]any{
345345
"v": "abc",
346346
}).Bind(&s)
347347
assert.ThatError(t, err).Matches("strconv.ParseFloat: parsing .*: invalid syntax")
@@ -351,7 +351,7 @@ func TestProperties_Bind(t *testing.T) {
351351
var s struct {
352352
Value bool `value:"${v}"`
353353
}
354-
err := conf.Map(map[string]interface{}{
354+
err := conf.Map(map[string]any{
355355
"v": "abc",
356356
}).Bind(&s)
357357
assert.ThatError(t, err).Matches("strconv.ParseBool: parsing .*: invalid syntax")
@@ -361,8 +361,8 @@ func TestProperties_Bind(t *testing.T) {
361361
var s struct {
362362
Value []int `value:"${v}"`
363363
}
364-
err := conf.Map(map[string]interface{}{
365-
"v": []interface{}{
364+
err := conf.Map(map[string]any{
365+
"v": []any{
366366
"1", "2", "a",
367367
},
368368
}).Bind(&s)
@@ -397,8 +397,8 @@ func TestProperties_Bind(t *testing.T) {
397397
var s struct {
398398
Value map[string]int `value:"${v}"`
399399
}
400-
err := conf.Map(map[string]interface{}{
401-
"v": []interface{}{
400+
err := conf.Map(map[string]any{
401+
"v": []any{
402402
"1", "2", "3",
403403
},
404404
}).Bind(&s)
@@ -409,7 +409,7 @@ func TestProperties_Bind(t *testing.T) {
409409
var s struct {
410410
Value map[string]int `value:"${v}"`
411411
}
412-
err := conf.Map(map[string]interface{}{
412+
err := conf.Map(map[string]any{
413413
"v": "a:b,1:2",
414414
}).Bind(&s)
415415
assert.ThatError(t, err).Matches("property conflict at path v")
@@ -437,7 +437,7 @@ func TestProperties_Bind(t *testing.T) {
437437
var s struct {
438438
int `value:"${v}"`
439439
}
440-
err := conf.Map(map[string]interface{}{
440+
err := conf.Map(map[string]any{
441441
"v": "123",
442442
}).Bind(&s)
443443
assert.Nil(t, err)
@@ -574,7 +574,7 @@ func TestProperties_Bind(t *testing.T) {
574574

575575
v := reflect.ValueOf(&s).Elem()
576576
err = conf.BindValue(conf.New(), v, v.Type(), param,
577-
funcFilter(func(i interface{}, param conf.BindParam) (bool, error) {
577+
funcFilter(func(i any, param conf.BindParam) (bool, error) {
578578
return false, nil
579579
}))
580580
assert.Nil(t, err)
@@ -592,7 +592,7 @@ func TestProperties_Bind(t *testing.T) {
592592

593593
v := reflect.ValueOf(&s).Elem()
594594
err = conf.BindValue(conf.New(), v, v.Type(), param,
595-
funcFilter(func(i interface{}, param conf.BindParam) (bool, error) {
595+
funcFilter(func(i any, param conf.BindParam) (bool, error) {
596596
return true, nil
597597
}))
598598
assert.Nil(t, err)
@@ -610,7 +610,7 @@ func TestProperties_Bind(t *testing.T) {
610610

611611
v := reflect.ValueOf(&s).Elem()
612612
err = conf.BindValue(conf.New(), v, v.Type(), param,
613-
funcFilter(func(i interface{}, param conf.BindParam) (bool, error) {
613+
funcFilter(func(i any, param conf.BindParam) (bool, error) {
614614
return false, errors.New("filter error")
615615
}))
616616
assert.ThatError(t, err).Matches("filter error")

conf/conf.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package conf
1919
import (
2020
"errors"
2121
"fmt"
22+
"maps"
2223
"os"
2324
"path/filepath"
2425
"reflect"
@@ -37,7 +38,7 @@ import (
3738
var (
3839
readers = map[string]Reader{}
3940
splitters = map[string]Splitter{}
40-
converters = map[reflect.Type]interface{}{}
41+
converters = map[reflect.Type]any{}
4142
)
4243

4344
func init() {
@@ -56,8 +57,8 @@ func init() {
5657
})
5758
}
5859

59-
// Reader parses []byte into nested map[string]interface{}.
60-
type Reader func(b []byte) (map[string]interface{}, error)
60+
// Reader parses []byte into nested map[string]any.
61+
type Reader func(b []byte) (map[string]any, error)
6162

6263
// RegisterReader registers its Reader for some kind of file extension.
6364
func RegisterReader(r Reader, ext ...string) {
@@ -99,7 +100,7 @@ type Properties interface {
99100
// Resolve resolves string that contains references.
100101
Resolve(s string) (string, error)
101102
// Bind binds properties into a value.
102-
Bind(i interface{}, tag ...string) error
103+
Bind(i any, tag ...string) error
103104
// CopyTo copies properties into another by override.
104105
CopyTo(out *MutableProperties) error
105106
}
@@ -148,7 +149,7 @@ func Load(file string) (*MutableProperties, error) {
148149
}
149150

150151
// Map creates *MutableProperties from map.
151-
func Map(m map[string]interface{}) *MutableProperties {
152+
func Map(m map[string]any) *MutableProperties {
152153
p := New()
153154
_ = p.merge(util.FlattenMap(m))
154155
return p
@@ -167,9 +168,7 @@ func (p *MutableProperties) merge(m map[string]string) error {
167168
// Data returns key-value pairs of the properties.
168169
func (p *MutableProperties) Data() map[string]string {
169170
m := make(map[string]string)
170-
for k, v := range p.RawData() {
171-
m[k] = v
172-
}
171+
maps.Copy(m, p.RawData())
173172
return m
174173
}
175174

@@ -199,7 +198,7 @@ func (p *MutableProperties) Resolve(s string) (string, error) {
199198
// value:"${a:=b}>>splitter", 'a' is the key, 'b' is the default value,
200199
// 'splitter' is the Splitter's name when you want split string value
201200
// into []string value.
202-
func (p *MutableProperties) Bind(i interface{}, tag ...string) error {
201+
func (p *MutableProperties) Bind(i any, tag ...string) error {
203202

204203
var v reflect.Value
205204
{

conf/conf_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestProperties_Load(t *testing.T) {
5959
func TestProperties_Resolve(t *testing.T) {
6060

6161
t.Run("success - 1", func(t *testing.T) {
62-
p := conf.Map(map[string]interface{}{
62+
p := conf.Map(map[string]any{
6363
"a.b.c": []string{"3"},
6464
})
6565
s, err := p.Resolve("${a.b.c[0]}")
@@ -68,7 +68,7 @@ func TestProperties_Resolve(t *testing.T) {
6868
})
6969

7070
t.Run("success - 2", func(t *testing.T) {
71-
p := conf.Map(map[string]interface{}{
71+
p := conf.Map(map[string]any{
7272
"a.b.c": []string{"3"},
7373
})
7474
s, err := p.Resolve("${x:=${a.b.c[0]}}")
@@ -90,23 +90,23 @@ func TestProperties_Resolve(t *testing.T) {
9090
})
9191

9292
t.Run("syntax error - 1", func(t *testing.T) {
93-
p := conf.Map(map[string]interface{}{
93+
p := conf.Map(map[string]any{
9494
"a.b.c": []string{"3"},
9595
})
9696
_, err := p.Resolve("${a.b.c}")
9797
assert.ThatError(t, err).Matches("property a.b.c isn't simple value")
9898
})
9999

100100
t.Run("syntax error - 2", func(t *testing.T) {
101-
p := conf.Map(map[string]interface{}{
101+
p := conf.Map(map[string]any{
102102
"a.b.c": []string{"3"},
103103
})
104104
_, err := p.Resolve("${a.b.c")
105105
assert.ThatError(t, err).Matches("resolve string .* error: invalid syntax")
106106
})
107107

108108
t.Run("syntax error - 3", func(t *testing.T) {
109-
p := conf.Map(map[string]interface{}{
109+
p := conf.Map(map[string]any{
110110
"a.b.c": []string{"3"},
111111
})
112112
_, err := p.Resolve("${a.b.c[0]}==${a.b.c}")
@@ -117,7 +117,7 @@ func TestProperties_Resolve(t *testing.T) {
117117
func TestProperties_CopyTo(t *testing.T) {
118118

119119
t.Run("success", func(t *testing.T) {
120-
p := conf.Map(map[string]interface{}{
120+
p := conf.Map(map[string]any{
121121
"a.b.c": []string{"3"},
122122
})
123123
assert.That(t, p.Keys()).Equal([]string{
@@ -131,7 +131,7 @@ func TestProperties_CopyTo(t *testing.T) {
131131
"a.b.c[0]": "3",
132132
})
133133

134-
s := conf.Map(map[string]interface{}{
134+
s := conf.Map(map[string]any{
135135
"a.b.c": []string{"4", "5"},
136136
})
137137
assert.That(t, s.Keys()).Equal([]string{
@@ -156,14 +156,14 @@ func TestProperties_CopyTo(t *testing.T) {
156156
})
157157

158158
t.Run("error", func(t *testing.T) {
159-
p := conf.Map(map[string]interface{}{
159+
p := conf.Map(map[string]any{
160160
"a.b.c": []string{"3"},
161161
})
162162
assert.That(t, p.Data()).Equal(map[string]string{
163163
"a.b.c[0]": "3",
164164
})
165165

166-
s := conf.Map(map[string]interface{}{
166+
s := conf.Map(map[string]any{
167167
"a.b.c": "3",
168168
})
169169
assert.That(t, s.Get("a.b.c")).Equal("3")
@@ -177,20 +177,20 @@ func BenchmarkResolve(b *testing.B) {
177177
const src = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
178178

179179
data := make([]byte, 2000)
180-
for i := 0; i < len(data); i++ {
180+
for i := range len(data) {
181181
data[i] = src[rand.Intn(len(src))]
182182
}
183183
s := string(data)
184184

185185
b.Run("contains", func(b *testing.B) {
186-
for i := 0; i < b.N; i++ {
186+
for b.Loop() {
187187
_ = strings.Contains(s, "${")
188188
}
189189
})
190190

191191
p := conf.New()
192192
b.Run("resolve", func(b *testing.B) {
193-
for i := 0; i < b.N; i++ {
193+
for b.Loop() {
194194
_, _ = p.Resolve(s)
195195
}
196196
})

conf/expr.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package conf
1818

1919
import (
2020
"fmt"
21+
"maps"
2122

2223
"github.com/expr-lang/expr"
2324
)
@@ -27,7 +28,7 @@ import (
2728
type ValidateFunc[T any] func(T) bool
2829

2930
// validateFuncs holds a map of registered validation functions.
30-
var validateFuncs = map[string]interface{}{}
31+
var validateFuncs = map[string]any{}
3132

3233
// RegisterValidateFunc registers a validation function with a specific name.
3334
// The function can then be used in validation expressions.
@@ -38,11 +39,9 @@ func RegisterValidateFunc[T any](name string, fn ValidateFunc[T]) {
3839
// validateField validates a field using a validation expression (tag) and the field value (i).
3940
// It evaluates the expression and checks if the result is true (i.e., the validation passes).
4041
// If any error occurs during evaluation or if the validation fails, an error is returned.
41-
func validateField(tag string, i interface{}) error {
42-
env := map[string]interface{}{"$": i}
43-
for k, v := range validateFuncs {
44-
env[k] = v
45-
}
42+
func validateField(tag string, i any) error {
43+
env := map[string]any{"$": i}
44+
maps.Copy(env, validateFuncs)
4645
r, err := expr.Eval(tag, env)
4746
if err != nil {
4847
return fmt.Errorf("eval %q returns error, %w", tag, err)

conf/expr_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestExpr(t *testing.T) {
3232
var v struct {
3333
A int `value:"${a}" expr:"checkInt($)"`
3434
}
35-
p := conf.Map(map[string]interface{}{
35+
p := conf.Map(map[string]any{
3636
"a": 4,
3737
})
3838
err := p.Bind(&v)
@@ -44,7 +44,7 @@ func TestExpr(t *testing.T) {
4444
var v struct {
4545
A int `value:"${a}" expr:"checkInt($)"`
4646
}
47-
p := conf.Map(map[string]interface{}{
47+
p := conf.Map(map[string]any{
4848
"a": 14,
4949
})
5050
err := p.Bind(&v)
@@ -55,7 +55,7 @@ func TestExpr(t *testing.T) {
5555
var v struct {
5656
A int `value:"${a}" expr:"$+$"`
5757
}
58-
p := conf.Map(map[string]interface{}{
58+
p := conf.Map(map[string]any{
5959
"a": 4,
6060
})
6161
err := p.Bind(&v)

conf/reader/json/json.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import (
2121
)
2222

2323
// Read parses []byte in the json format into map.
24-
func Read(b []byte) (map[string]interface{}, error) {
25-
var ret map[string]interface{}
24+
func Read(b []byte) (map[string]any, error) {
25+
var ret map[string]any
2626
err := json.Unmarshal(b, &ret)
2727
if err != nil {
2828
return nil, err

conf/reader/json/json_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestRead(t *testing.T) {
4040
"time": "2018-02-17T15:02:31+08:00"
4141
}`))
4242
assert.Nil(t, err)
43-
assert.That(t, r).Equal(map[string]interface{}{
43+
assert.That(t, r).Equal(map[string]any{
4444
"empty": "",
4545
"bool": false,
4646
"int": float64(3),

0 commit comments

Comments
 (0)