go 语言解析yaml,告别一个文件一个struct

yaml文件是现在很流行的一种配置文件,具有结构清晰,层次分明的特点。它是json的一个超集,解析出来的内容在python中对应着字典,go语言中可以解析为结构体。

曾经作为初学者,现在依旧是初学者的我,用go解析yaml文件,也是一个文件定义一次结构体,结构体中定义大量的tag是非常繁琐的工作。于是我就自己写了一个代码,解析为一个通用的map,并序列化为json,为什么序列化为json呢,方便以后web交换数据,或者跨语言的使用。

直接上代码:

package config


/*the interface load config yaml file,return json and error*/
type Config interface {
	LoadConfigl(file string) (jsonByte []byte, err error)
}

/*
the default config 
you can implement config
if you do not implement,will use default config
that will be used for Configuration Center in the future
*/
type defaultConfig map[string]interface{}

通过定义一个Config接口签名Loadconfig方法。

定义一个defaultconfig 的type 用于解析yaml

package config

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strings"
	yaml "gopkg.in/yaml.v3"
)


/*
load yaml config
return json data and error 
*/
func (dc *defaultConfig)loadyaml(file string)(jsonByte []byte,err error){
	confile,ok := os.Open(file)
	err = ok
	if err != nil {
		return
	}
	defer confile.Close()
	
		
	configmaps := []defaultConfig{}	
	dec := yaml.NewDecoder(confile)
	
	for err == nil {//decode yaml file if err != nil
		cf := defaultConfig{}
		err = dec.Decode(cf)
		if err != nil && err != io.EOF {
			return
		}
		if len(cf) != 0 { // if cf has key value append it
			configmaps =append(configmaps, cf)
		}				
	}
	if len(configmaps) == 1 {
		(*dc)["configs"] = configmaps[0] // pasre one file
	}else{
		(*dc)["configs"] = configmaps //pasre more than one file
	}		
	return dc.parseJosn()
}

func (dc *defaultConfig)LoadConfig(file string)(jsonByte []byte,err error){
	return dc.loadyaml(file)
}

/*pasre dc to json*/
func (dc *defaultConfig)parseJosn()([]byte,error){
	return json.Marshal(dc)
}

defaultConfig 通过实现Config的方法,实现了该接口。接着再来一个外部的方法,通过config,来实现解析yaml:

package config

import (
	"errors"
	"io/ioutil"
	"strings"
)

var(
	errfilesyntax error = errors.New("syntax erorr")
	errstyle error = errors.New("this is a unkonw type of the config file")
	erremptyinterface error = errors.New("the interface config is nil")
	erremptyfile error = errors.New("the config file is nil")
)

func Mashal(c Config,file string)(jsonstr []byte,err error){
	return mashal(c,file)
}

func mashal(c Config,file string)(jsonstr []byte,err error){    
    if c == nil {
		err = erremptyinterface
		return 
	}
	
	if file == "" {
		err = erremptyfile
		return
	}
	
	if strings.HasSuffix(file,".yaml") || strings.HasSuffix(file,".yml") {
		if jsonstr,err = c.LoadConfig(file);len(jsonstr)==0 && err == nil{ //如果自己实现的Config接口没有具体的实现,就会使用默认的config接口。这个主要是方便大家定制。 
			dcs := &defaultConfig{}
			c = dcs	
            return c.LoadConfig(file)		
		}
		return 
    } 
    		
	err = errstyle
	return 
}

func NewConfig()(Config){ //提供一个创建Config接口的方法。
	return &defaultConfig{}
}

到此能够让你解析所有yaml的go程序大体完成。你可以用通过gjosn去使用这个配置的json,也可以反序列化成你想要的结构体,map来使用这些yaml文件。 

你可能感兴趣的:(go,golang,开发语言,后端)