-
Notifications
You must be signed in to change notification settings - Fork 3
/
unmarshal.go
executable file
·86 lines (75 loc) · 2.86 KB
/
unmarshal.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
75
76
77
78
79
80
81
82
83
84
85
86
// Package viperKit
/*
支持的配置文件格式(详见viper.go):
"yaml", "yml", "json", "toml", "hcl", "tfvars",
"dotenv", "env",
"properties", "props", "prop",
"ini"
*/
package viperKit
import (
"github.com/mitchellh/mapstructure"
"github.com/richelieu-yang/chimera/v3/src/core/interfaceKit"
"github.com/richelieu-yang/chimera/v3/src/core/ptrKit"
"github.com/richelieu-yang/chimera/v3/src/file/fileKit"
"github.com/spf13/viper"
)
// Unmarshal 读取配置文本内容,并反序列化.
/*
@param configType 配置文件的类型(不区分大小写,详见viper.go):"yaml", "yml", "json", "toml", "hcl", "tfvars", "dotenv", "env", "properties", "props", "prop", "ini"
@param defaultMap 默认值,可以为nil
@param ptr 指针,且不能为nil
*/
func Unmarshal(content []byte, configType string, defaultMap map[string]interface{}, ptr interface{}) (*viper.Viper, error) {
if err := ptrKit.AssertNotNilAndIsPointer(ptr); err != nil {
return nil, err
}
v, err := Read(content, configType, defaultMap)
if err != nil {
return nil, err
}
err = v.Unmarshal(ptr, func(dc *mapstructure.DecoderConfig) {
// 如果指针ptr对应的类型是个子类的话,需要如此进行设置,否则父类的属性都会是对应类型的零值!
dc.Squash = true
})
if err != nil {
return nil, err
}
return v, nil
}
func UnmarshalFromData(data *Data, defaultMap map[string]interface{}, ptr interface{}) (*viper.Viper, error) {
if err := interfaceKit.AssertNotNil(data, "data"); err != nil {
return nil, err
}
return Unmarshal(data.Content, data.Type, defaultMap, ptr)
}
// UnmarshalFromFile 读取配置文件,并反序列化.
/*
Deprecated: 反序列化.yaml文件,先用 yamlKit.UnmarshalFromFile 替换 viperKit.UnmarshalFromFile,原因: https://github.com/spf13/viper/issues/1769
PS:
(1) 配置文件 和 defaultMap 中,key首字母的大小写无所谓,都支持;
(2) 支持配置文件的格式:JSON, TOML, HCL, .env, .yaml, .properties.
@param filePath 配置文件的路径(绝对路径 和 相对路径 都支持),内部会判断文件是否存在
@param defaultMap (可以为nil) 默认值;key如果有多层的话,用"."分隔,e.g. "WoService.LowerLimit"
@param ptr (不能为nil) 指针
*/
func UnmarshalFromFile(filePath string, defaultMap map[string]interface{}, ptr interface{}) (*viper.Viper, error) {
if err := fileKit.AssertExistAndIsFile(filePath); err != nil {
return nil, err
}
if err := ptrKit.AssertNotNilAndIsPointer(ptr); err != nil {
return nil, err
}
v, err := ReadFile(filePath, defaultMap)
if err != nil {
return nil, err
}
err = v.Unmarshal(ptr, func(dc *mapstructure.DecoderConfig) {
// 如果指针ptr对应的类型是个子类的话,需要如此进行设置,否则父类的属性都会是对应类型的零值!
dc.Squash = true
})
if err != nil {
return nil, err
}
return v, nil
}