TOML 旨在成为一个语义明显且易于阅读的最小化配置文件格式。TOML 被设计成可以无歧义地映射为哈希表。TOML 应该能很容易地被解析成各种语言中的数据结构。

toml

代码

  1package main
  2
  3import (
  4	"bytes"
  5	"encoding/json"
  6	"fmt"
  7
  8	"github.com/BurntSushi/toml"
  9	"github.com/tidwall/pretty"
 10
 11	log "github.com/sirupsen/logrus"
 12)
 13
 14func format(source any) {
 15	value, err := json.Marshal(source)
 16	if err != nil {
 17		log.Error(err)
 18	}
 19	// 接收管道
 20	option := &pretty.Options{Width: 80, Prefix: "", Indent: "\t", SortKeys: false}
 21	fmt.Printf("%s\n", pretty.PrettyOptions(value, option))
 22}
 23
 24/**
 25 * {
 26 *  	"Key": "key的名字",
 27 *  	"Another": "# 这不是一个注释",
 28 *  	"User": {
 29 *  		"Name": "admin",
 30 *  		"Password": "123456"
 31 *  	},
 32 *  	"Domain": {
 33 *  		"clibing.com": true
 34 *  	}
 35 *  }
 36 */
 37func demo_01() {
 38	value := `
 39# 注释 1
 40key = "key的名字" # 注释 2
 41another = "# 这不是一个注释"
 42
 43user.name = "admin"
 44user.password = "123456"
 45
 46domain."clibing.com" = true
 47
 48	`
 49	log.Infof(value)
 50
 51	type User struct {
 52		Name     string `toml:"name"`
 53		Password string `toml:"password"`
 54	}
 55
 56	type Config struct {
 57		Key     string          `toml:"key"`
 58		Another string          `toml:"another"`
 59		User    User            `toml:"user"`
 60		Domain  map[string]bool `toml:"domain"`
 61	}
 62
 63	var config Config
 64	metaData, err := toml.Decode(value, &config)
 65	if err != nil {
 66		log.Info("decode toml faild", err)
 67	}
 68
 69	for _, v := range metaData.Keys() {
 70		log.WithField("key", v).Info("读取配置")
 71	}
 72
 73	log.WithFields(log.Fields{
 74		"key":      config.Key,
 75		"another":  config.Another,
 76		"name":     config.User.Name,
 77		"password": config.User.Password,
 78		"domain":   fmt.Sprintf("%v", config.Domain),
 79	}).Info("打印反序列化")
 80
 81	format(config)
 82}
 83
 84/**
 85 * {
 86*   	"Name": "demo 01",
 87*   	"User": {
 88*   		"Member": {
 89*   			"Level": "普通会员",
 90*   			"Enable": true
 91*   		}
 92*   	}
 93*   }
 94*/
 95func demo_02() {
 96	value := `
 97name = "demo 01"
 98user.member.level = "普通会员"
 99user.member.enable = true
100	`
101
102	type Member struct {
103		Level  string `toml:"level"`
104		Enable bool   `toml:"enable"`
105	}
106
107	type User struct {
108		Member *Member `toml:"member"`
109	}
110
111	type Config struct {
112		Name string `toml:"name"`
113		User *User  `toml:"user"`
114	}
115
116	var config Config
117	toml.Decode(value, &config)
118
119	log.Info(value)
120
121	format(config)
122}
123
124type AutoGenerated struct {
125	Spring Spring `json:"spring"`
126}
127type Application struct {
128	Name string `json:"name"`
129}
130type Main struct {
131	BannerMode string `json:"banner-mode"`
132}
133type Sentinel struct {
134	Master string `json:"master"`
135	Nodes  string `json:"nodes"`
136}
137type Pool struct {
138	MaxActive int    `json:"max-active"`
139	MaxIdle   int    `json:"max-idle"`
140	MaxWait   string `json:"max-wait"`
141	MinIdle   int    `json:"min-idle"`
142}
143type Lettuce struct {
144	Pool Pool `json:"pool"`
145}
146type Redis struct {
147	Database int      `json:"database"`
148	Password string   `json:"password"`
149	Sentinel Sentinel `json:"sentinel"`
150	Lettuce  Lettuce  `json:"lettuce"`
151	Timeout  string   `json:"timeout"`
152}
153type Datasource struct {
154	URL             string `json:"url"`
155	DriverClassName string `json:"driverClassName"`
156	Username        string `json:"username"`
157	Password        string `json:"password"`
158	ValidationQuery string `json:"validation-query"`
159	TestWhileIdle   bool   `json:"test-while-idle"`
160	TestOnBorrow    bool   `json:"test-on-borrow"`
161}
162type Spring struct {
163	Application Application `json:"application"`
164	Main        Main        `json:"main"`
165	Redis       Redis       `json:"redis"`
166	Datasource  Datasource  `json:"datasource"`
167}
168
169func demo_03() {
170
171	value := `
172{
173  "spring": {
174    "application": {
175      "name": "toml"
176    },
177    "main": {
178      "banner-mode": "console"
179    },
180    "redis": {
181      "database": 0,
182      "password": "123456",
183      "sentinel": {
184        "master": "master",
185        "nodes": "redis-0.local:26379,redis-1:26379,redis-2:26379"
186      },
187      "lettuce": {
188        "pool": {
189          "max-active": 8,
190          "max-idle": 8,
191          "max-wait": "1ms",
192          "min-idle": 0
193        }
194      },
195      "timeout": "3000ms"
196    },
197    "datasource": {
198      "url": "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&useSSL=false",
199      "driverClassName": "com.mysql.jdbc.Driver",
200      "username": "root",
201      "password": "root",
202      "validation-query": "SELECT 1",
203      "test-while-idle": true,
204      "test-on-borrow": true
205    }
206  }
207}
208`
209
210	var autoGenerated AutoGenerated
211
212	err := json.Unmarshal([]byte(value), &autoGenerated)
213	if err != nil {
214		log.Debug(err)
215		return
216	}
217
218	buf := new(bytes.Buffer)
219
220	err = toml.NewEncoder(buf).Encode(autoGenerated)
221	if err != nil {
222		log.Debug(err)
223		return
224	}
225	fmt.Println(buf.String())
226	// log.Info(buf.String())
227}
228
229func main() {
230	log.Info("tomal load & read & parse & save.")
231	demo_01()
232	demo_02()
233	demo_03()
234}

json & yml & toml 对比

 1{
 2  "spring": {
 3    "application": {
 4      "name": "toml"
 5    },
 6    "main": {
 7      "banner-mode": "console"
 8    },
 9    "redis": {
10      "database": 0,
11      "password": "123456",
12      "sentinel": {
13        "master": "master",
14        "nodes": "redis-0.local:26379,redis-1:26379,redis-2:26379"
15      },
16      "lettuce": {
17        "pool": {
18          "max-active": 8,
19          "max-idle": 8,
20          "max-wait": "1ms",
21          "min-idle": 0
22        }
23      },
24      "timeout": "3000ms"
25    },
26    "datasource": {
27      "url": "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&useSSL=false",
28      "driverClassName": "com.mysql.jdbc.Driver",
29      "username": "root",
30      "password": "root",
31      "validation-query": "SELECT 1",
32      "test-while-idle": true,
33      "test-on-borrow": true
34    }
35  }
36}
 1spring:
 2  application:
 3    name: toml
 4  main:
 5    banner-mode: console
 6  redis:
 7    database: 0
 8    password: '123456'
 9    sentinel:
10      master: master
11      nodes: redis-0.local:26379,redis-1:26379,redis-2:26379
12    lettuce:
13      pool:
14        max-active: 8
15        max-idle: 8
16        max-wait: 1ms
17        min-idle: 0
18    timeout: 3000ms
19  datasource:
20    url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&useSSL=false
21    driverClassName: com.mysql.jdbc.Driver
22    username: root
23    password: root
24    validation-query: SELECT 1
25    test-while-idle: true
26    test-on-borrow: true
 1[Spring]
 2  [Spring.Application]
 3    Name = "toml"
 4  [Spring.Main]
 5    BannerMode = "console"
 6  [Spring.Redis]
 7    Database = 0
 8    Password = "123456"
 9    Timeout = "3000ms"
10    [Spring.Redis.Sentinel]
11      Master = "master"
12      Nodes = "redis-0.local:26379,redis-1:26379,redis-2:26379"
13    [Spring.Redis.Lettuce]
14      [Spring.Redis.Lettuce.Pool]
15        MaxActive = 8
16        MaxIdle = 8
17        MaxWait = "1ms"
18        MinIdle = 0
19  [Spring.Datasource]
20    URL = "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&useSSL=false"
21    DriverClassName = "com.mysql.jdbc.Driver"
22    Username = "root"
23    Password = "root"
24    ValidationQuery = "SELECT 1"
25    TestWhileIdle = true
26    TestOnBorrow = true