gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/config/parser.go (about)

     1  package config
     2  
     3  import (
     4  	"os"
     5  )
     6  
     7  type parser interface {
     8  	Unmarshal(c interface{}) error
     9  }
    10  
    11  type Parser struct {
    12  	parsers []parser
    13  }
    14  
    15  func (p *Parser) AddBytes(bs []byte, typ Type) {
    16  	p.parsers = append(p.parsers, &bytesParser{
    17  		bytes: bs,
    18  		typ:   typ,
    19  	})
    20  }
    21  
    22  func (p *Parser) SetBytes(bs []byte, typ Type) {
    23  	p.parsers = p.parsers[:0]
    24  	p.AddBytes(bs, typ)
    25  }
    26  
    27  func (p *Parser) AddFile(path string, typ *Type) {
    28  	var t Type
    29  	if typ == nil {
    30  		t = ProbeType(path)
    31  	} else {
    32  		t = *typ
    33  	}
    34  	p.parsers = append(p.parsers, &fileParser{
    35  		path: path,
    36  		typ:  t,
    37  	})
    38  }
    39  
    40  func (p *Parser) SetFile(path string, typ *Type) {
    41  	p.parsers = p.parsers[:0]
    42  	p.AddFile(path, typ)
    43  }
    44  
    45  func (p *Parser) AddFilePrefix(prefix string, types ...Type) {
    46  	group := &parserGroup{errorIgnore: os.IsNotExist}
    47  	for _, typ := range types {
    48  		for _, suffix := range typ.Suffixes {
    49  			group.parsers = append(group.parsers, &fileParser{
    50  				path: prefix + "." + suffix,
    51  				typ:  typ,
    52  			})
    53  		}
    54  	}
    55  	p.parsers = append(p.parsers, group)
    56  }
    57  
    58  func (p *Parser) SetFilePrefix(prefix string, types ...Type) {
    59  	p.parsers = p.parsers[:0]
    60  	p.AddFilePrefix(prefix, types...)
    61  }
    62  
    63  func (p *Parser) Unmarshal(c interface{}) error {
    64  	if err := HandleDefault(c); err != nil {
    65  		return err
    66  	}
    67  	if err := PreHandle(c); err != nil {
    68  		return err
    69  	}
    70  	for _, parser := range p.parsers {
    71  		err := parser.Unmarshal(c)
    72  		if err != nil {
    73  			return err
    74  		}
    75  	}
    76  	if err := PostHandle(c); err != nil {
    77  		return err
    78  	}
    79  	return nil
    80  }
    81  
    82  //
    83  //type configFile struct {
    84  //	path           string
    85  //	data           []byte
    86  //	typ            Type
    87  //	ignoreNotExist bool
    88  //}
    89  //
    90  //
    91  //
    92  //type Parser struct {
    93  //	configs []configFile
    94  //}
    95  //
    96  //func Exist(path string) bool {
    97  //	stat, err := os.Stat(path)
    98  //	if err != nil {
    99  //		return false
   100  //	}
   101  //	return stat.Mode().IsRegular()
   102  //}
   103  //
   104  //func (p *Parser) SetConfigFilePrefix(prefix string, types ...*Type) {
   105  //	p.SetConfigFilePrefixIgnoreNotExist(prefix, types...)
   106  //	p.configs[len(p.configs)-1].ignoreNotExist = false
   107  //}
   108  //
   109  //func (p *Parser) SetConfigFilePrefixIgnoreNotExist(prefix string, types ...*Type) {
   110  //	p.configs = p.configs[:0]
   111  //	for _, typ := range types {
   112  //		for _, suffix := range typ.Suffixes {
   113  //			p.configs = append(p.configs, configFile{
   114  //				path:           prefix + "." + suffix,
   115  //				typ:            *typ,
   116  //				ignoreNotExist: true,
   117  //			})
   118  //		}
   119  //	}
   120  //	p.configs = append(p.configs, configFile{
   121  //		path: prefix,
   122  //	})
   123  //}
   124  //
   125  //func (p *Parser) SetConfigFile(path string, typ *Type) {
   126  //	p.setConfigFile(path, typ, false)
   127  //}
   128  //
   129  //func (p *Parser) SetConfigFileIgnoreNotExist(path string, typ *Type) {
   130  //	p.setConfigFile(path, typ, true)
   131  //}
   132  //
   133  //func (p *Parser) setConfigFile(path string, typ *Type, ignoreNotExist bool) {
   134  //	var t Type
   135  //	if typ == nil {
   136  //		t = ProbeType(path)
   137  //	} else {
   138  //		t = *typ
   139  //	}
   140  //	p.configs = []configFile{{path: path, typ: t, ignoreNotExist: ignoreNotExist}}
   141  //}
   142  //
   143  //func (p *Parser) AddConfigFile(path string, typ *Type) {
   144  //	p.addConfigFile(path, typ, false)
   145  //}
   146  //
   147  //func (p *Parser) AddConfigFileIgnoreNotExist(path string, typ *Type) {
   148  //	p.addConfigFile(path, typ, true)
   149  //}
   150  //
   151  //func (p *Parser) addConfigFile(path string, typ *Type, ignoreNotExist bool) {
   152  //	var t Type
   153  //	if typ == nil {
   154  //		t = ProbeType(path)
   155  //	} else {
   156  //		t = *typ
   157  //	}
   158  //	p.configs = append(p.configs, configFile{path: path, typ: t, ignoreNotExist: ignoreNotExist})
   159  //}
   160  //
   161  //func (p *Parser) Unmarshal(c interface{}) error {
   162  //	// invoke config pre handle
   163  //	handle(preHandler{}, c, make(map[interface{}]struct{}))
   164  //	var notExistErrors error
   165  //	for i, config := range p.configs {
   166  //		info, err := os.Stat(config.path)
   167  //		if err != nil {
   168  //			if os.IsNotExist(err) {
   169  //				notExistErrors = errors.Append(notExistErrors, err)
   170  //				if config.ignoreNotExist {
   171  //					continue
   172  //				}
   173  //				return notExistErrors
   174  //			}
   175  //			return err
   176  //		}
   177  //		if info.Len() > MaxConfigFileSize {
   178  //			return errors.New("config file size too large")
   179  //		}
   180  //		data, err := os.ReadFile(config.path)
   181  //		if err != nil {
   182  //			return err
   183  //		}
   184  //		p.configs[i].data = data
   185  //	}
   186  //
   187  //out:
   188  //	// parse config
   189  //	for _, config := range p.configs {
   190  //		if config.typ.Id == TypeUnknown.Id {
   191  //			var es error
   192  //			for _, tpy := range types {
   193  //				if tpy.Unmarshaler != nil {
   194  //					if err := config.typ.Unmarshaler(config.data, c); err != nil {
   195  //						// retry next unmarshaler parse config
   196  //						errors.Append(es, err)
   197  //						continue
   198  //					}
   199  //					// parse config success
   200  //					continue out
   201  //				}
   202  //			}
   203  //			// all unmarshaler parse config failed
   204  //			return es
   205  //		} else {
   206  //			if err := config.typ.Unmarshaler(config.data, c); err != nil {
   207  //				return err
   208  //			}
   209  //		}
   210  //	}
   211  //
   212  //	// invoke config post handle
   213  //	_, _, err := handle(postHandler{}, c, make(map[interface{}]struct{}))
   214  //	return err
   215  //}