TOML:
GitHub 目前的新项目已经转用 CoffeeScript 了。CoffeeScript 比 JavaScript 要简洁优雅得多。同样地,GitHub 也觉得 YAML 不够简洁优雅,因此捣鼓出了一个 TOML。
TOML 的目标是成为一个极简的配置文件格式。TOML 被设计成可以无歧义地被映射为哈希表,从而被多种语言解析。
例子
title = "TOML 例子"[owner] name = "Tom Preston-Werner" organization = "GitHub" bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." dob = 1979-05-27T07:32:00Z # 日期时间是一等公民。为什么不呢? [database] server = "192.168.1.1" ports = [ 8001, 8001, 8002 ] connection_max = 5000enabled = true[servers] # 你可以依照你的意愿缩进。使用空格或Tab。TOML不会在意。 [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.beta] ip = "10.0.0.2" dc = "eqdc10"[clients] data = [ ["gamma", "delta"], [1, 2] ]# 在数组里换行没有关系。hosts = [ "alpha", "omega"]
TOML 是大小写敏感的。
func ReplaceEnvsFile(path string) (string, error) {
file, err := os.Open(path)
if err != nil {
return "", err
}
r, err := EnvSub(file)
if err != nil {
return "", err
}
contents, err := ioutil.ReadAll(r)
if err != nil {
return "", err
}
return string(contents), nil
}
func EnvSub(r io.Reader) (io.Reader, error) {
bufIn := bufio.NewReader(r)
bufOut := new(bytes.Buffer)
for {
chunk, err := bufIn.ReadBytes(byte(‘%‘))
if err != nil {
if err == io.EOF {
// We‘re done.
bufOut.Write(chunk)
break
}
return nil, err
}
bufOut.Write(chunk[:len(chunk)-1])
tmp := make([]byte, 4)
tmp, err = bufIn.Peek(4)
if err != nil {
if err == io.EOF {
// End of file, write the last few bytes out and exit.
bufOut.WriteRune(‘%‘)
bufOut.Write(tmp)
break
}
return nil, err
}
if string(tmp) == "ENV[" {
// Found opening delimiter, advance the read cursor and look for
// closing delimiter.
tmp, err = bufIn.ReadBytes(byte(‘[‘))
if err != nil {
// This shouldn‘t happen, since the Peek succeeded.
return nil, err
}
chunk, err = bufIn.ReadBytes(byte(‘]‘))
if err != nil {
if err == io.EOF {
// No closing delimiter, return an error
return nil, ErrMissingCloseDelim
}
return nil, err
}
// `chunk` is now holding var name + closing delimiter.
// var name contains invalid characters, return an error
if bytes.IndexAny(chunk, invalidEnvChars) != -1 ||
bytes.Index(chunk, invalidEnvPrefix) != -1 {
return nil, ErrInvalidChars
}
varName := string(chunk[:len(chunk)-1])
varVal := os.Getenv(varName)
bufOut.WriteString(varVal)
} else {
// Just a random ‘%‘, not an opening delimiter, write it out and
// keep going.
bufOut.WriteRune(‘%‘)
}
}
return bufOut, nil
}
func main(){
contents, err := ReplaceEnvsFile("test.toml")
if err != nil {
return err
}
if _, err = toml.Decode(contents, &configFile); err != nil {
return fmt.Errorf("Error decoding config file: %s", err)
}
}
配置文件test.toml
[hekad]
share_dir="/usr/local/heka"
输出内容为:
map[hekad:map[share_dir:/usr/local/heka]]
原文:http://my.oschina.net/yang1992/blog/511914