@@ -29,16 +29,19 @@ func configSplit(raw, sep string) []string {
2929}
3030
3131//NewConfig 加载配置文件.
32- func NewConfig (path string ) (c * Config , err error ) {
33- dat , err := ioutil .ReadFile (path )
34- if err != nil {
35- return nil , err
32+ func NewConfig (path , body string ) (c * Config , err error ) {
33+ if path != "" {
34+ dat , err := ioutil .ReadFile (path )
35+ if err != nil {
36+ return nil , err
37+ }
38+ body = string (dat )
3639 }
3740
3841 c = & Config {kv : make (map [string ]string )}
3942 s := ""
4043
41- for _ , line := range strings .Split (string ( dat ) , "\n " ) {
44+ for _ , line := range strings .Split (body , "\n " ) {
4245 line = strings .TrimSpace (line )
4346 if len (line ) < 3 || line [0 ] == ';' || line [0 ] == '#' {
4447 continue
@@ -78,8 +81,7 @@ func (c *Config) GetData(s, k string, result interface{}, d interface{}) error {
7881 if ! ok {
7982 //没有对应的key, 这时候要看看有没有default.
8083 if d == nil {
81- fmt .Printf ("kv:%#v, key:%v\n " , c .kv , key )
82- return errors .Annotatef (ErrNotFound , "%v:%v" , s , k )
84+ return errors .Annotatef (ErrNotFound , "%v->%v" , s , k )
8385 }
8486 rv .Set (reflect .ValueOf (d ))
8587 return nil
@@ -121,13 +123,98 @@ func (c *Config) GetData(s, k string, result interface{}, d interface{}) error {
121123 return nil
122124}
123125
126+ //ParseConfig 解析内存中配置文件.
127+ func ParseConfig (body string , result interface {}) error {
128+ c , err := NewConfig ("" , body )
129+ if err != nil {
130+ return errors .Trace (err )
131+ }
132+ return c .Parse (result )
133+ }
134+
124135//LoadConfig 加载文件形式配置文件, 并解析成指定结构.
125136func LoadConfig (path string , result interface {}) error {
126- c , err := NewConfig (path )
137+ c , err := NewConfig (path , "" )
127138 if err != nil {
128139 return errors .Trace (err )
129140 }
141+ return c .Parse (result )
142+ }
130143
144+ func (c Config ) getDefault (k reflect.Kind , v string ) (interface {}, error ) {
145+ switch k {
146+ case reflect .Uint :
147+ d , err := strconv .ParseUint (v , 10 , 64 )
148+ if err != nil {
149+ return nil , errors .Trace (err )
150+ }
151+ return uint (d ), nil
152+ case reflect .Uint8 :
153+ d , err := strconv .ParseUint (v , 10 , 64 )
154+ if err != nil {
155+ return nil , errors .Trace (err )
156+ }
157+ return uint8 (d ), nil
158+ case reflect .Uint16 :
159+ d , err := strconv .ParseUint (v , 10 , 64 )
160+ if err != nil {
161+ return nil , errors .Trace (err )
162+ }
163+ return uint16 (d ), nil
164+ case reflect .Uint32 :
165+ d , err := strconv .ParseUint (v , 10 , 64 )
166+ if err != nil {
167+ return nil , errors .Trace (err )
168+ }
169+ return uint32 (d ), nil
170+ case reflect .Uint64 :
171+ return strconv .ParseUint (v , 10 , 64 )
172+ case reflect .Int :
173+ d , err := strconv .ParseInt (v , 10 , 64 )
174+ if err != nil {
175+ return nil , errors .Trace (err )
176+ }
177+ return int (d ), nil
178+ case reflect .Int8 :
179+ d , err := strconv .ParseInt (v , 10 , 64 )
180+ if err != nil {
181+ return nil , errors .Trace (err )
182+ }
183+ return uint8 (d ), nil
184+ case reflect .Int16 :
185+ d , err := strconv .ParseInt (v , 10 , 64 )
186+ if err != nil {
187+ return nil , errors .Trace (err )
188+ }
189+ return uint16 (d ), nil
190+ case reflect .Int32 :
191+ d , err := strconv .ParseInt (v , 10 , 64 )
192+ if err != nil {
193+ return nil , errors .Trace (err )
194+ }
195+ return uint32 (d ), nil
196+ case reflect .Int64 :
197+ return strconv .ParseInt (v , 10 , 64 )
198+ case reflect .String :
199+ return v , nil
200+ case reflect .Bool :
201+ return strconv .ParseBool (v )
202+ case reflect .Float32 :
203+ d , err := strconv .ParseFloat (v , 32 )
204+ if err != nil {
205+ return nil , errors .Trace (err )
206+ }
207+ return float32 (d ), nil
208+ case reflect .Float64 :
209+ return strconv .ParseFloat (v , 32 )
210+
211+ default :
212+ return nil , Errunsupported
213+ }
214+ }
215+
216+ //Parse 根据result结构读配置文件.
217+ func (c * Config ) Parse (result interface {}) error {
131218 rt := reflect .TypeOf (result )
132219 rv := reflect .ValueOf (result )
133220
@@ -154,67 +241,42 @@ func LoadConfig(path string, result interface{}) error {
154241 ft = ft .Elem ()
155242 }
156243
157- if ft .Kind () == reflect .Struct {
158- for j := 0 ; j < ft .NumField (); j ++ {
159- sf := ft .Field (j )
160- if f .PkgPath != "" && ! f .Anonymous { // unexported
161- continue
162- }
163- sfv := fv .Field (j )
164- if sf .Type .Kind () == reflect .Ptr {
165- sfv = reflect .New (sfv .Elem ().Type ())
166- fv .Field (j ).Set (sfv )
167- }
244+ if ft .Kind () != reflect .Struct {
245+ continue
246+ }
168247
169- var d interface {}
170- if v := sf .Tag .Get ("default" ); v != "" {
171- switch sf .Type .Kind () {
172- case reflect .Uint :
173- d , err = strconv .ParseUint (v , 10 , 64 )
174- d = uint (d .(uint64 ))
175- case reflect .Uint8 :
176- d , err = strconv .ParseUint (v , 10 , 64 )
177- d = uint8 (d .(uint64 ))
178- case reflect .Uint16 :
179- d , err = strconv .ParseUint (v , 10 , 64 )
180- d = uint16 (d .(uint64 ))
181- case reflect .Uint32 :
182- d , err = strconv .ParseUint (v , 10 , 64 )
183- d = uint32 (d .(uint64 ))
184- case reflect .Uint64 :
185- d , err = strconv .ParseUint (v , 10 , 64 )
186- case reflect .Int :
187- d , err = strconv .ParseInt (v , 10 , 64 )
188- d = int (d .(int64 ))
189- case reflect .Int8 :
190- d , err = strconv .ParseInt (v , 10 , 64 )
191- d = uint8 (d .(uint64 ))
192- case reflect .Int16 :
193- d , err = strconv .ParseInt (v , 10 , 64 )
194- d = uint16 (d .(uint64 ))
195- case reflect .Int32 :
196- d , err = strconv .ParseInt (v , 10 , 64 )
197- d = uint32 (d .(uint64 ))
198- case reflect .Int64 :
199- d , err = strconv .ParseInt (v , 10 , 64 )
200- case reflect .String :
201- d = v
202- case reflect .Bool :
203- d , err = strconv .ParseBool (v )
204- case reflect .Float32 , reflect .Float64 :
205- d , err = strconv .ParseFloat (v , 32 )
206-
207- default :
208- return Errunsupported
209- }
210- }
248+ segment := f .Name
249+ if name := f .Tag .Get ("cfg_key" ); name != "" {
250+ segment = name
251+ }
252+
253+ for j := 0 ; j < ft .NumField (); j ++ {
254+ sf := ft .Field (j )
255+ if f .PkgPath != "" && ! f .Anonymous { // unexported
256+ continue
257+ }
258+ sfv := fv .Field (j )
259+ if sf .Type .Kind () == reflect .Ptr {
260+ sfv = reflect .New (sfv .Elem ().Type ())
261+ fv .Field (j ).Set (sfv )
262+ }
263+
264+ var cfgDefault interface {}
265+ if v := sf .Tag .Get ("cfg_default" ); v != "" {
266+ d , err := c .getDefault (sf .Type .Kind (), v )
211267 if err != nil {
212268 return errors .Trace (err )
213269 }
270+ cfgDefault = d
271+ }
214272
215- if err = c .GetData (f .Name , sf .Name , sfv .Addr ().Interface (), d ); err != nil {
216- return errors .Trace (err )
217- }
273+ key := sf .Name
274+ if name := sf .Tag .Get ("cfg_key" ); name != "" {
275+ key = name
276+ }
277+
278+ if err := c .GetData (segment , key , sfv .Addr ().Interface (), cfgDefault ); err != nil {
279+ return errors .Trace (err )
218280 }
219281 }
220282 }
0 commit comments