summaryrefslogtreecommitdiffstats
path: root/example_test.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 17:02:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 17:02:14 +0000
commite61c5fa98419989a61b5ca4eb7749acbd37e0af6 (patch)
treeffe04b0283921bd40489aaa74dcee1f68b7b6b35 /example_test.go
parentInitial commit. (diff)
downloadgolang-toml-e61c5fa98419989a61b5ca4eb7749acbd37e0af6.tar.xz
golang-toml-e61c5fa98419989a61b5ca4eb7749acbd37e0af6.zip
Adding upstream version 1.3.2.upstream/1.3.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'example_test.go')
-rw-r--r--example_test.go387
1 files changed, 387 insertions, 0 deletions
diff --git a/example_test.go b/example_test.go
new file mode 100644
index 0000000..eb51b4a
--- /dev/null
+++ b/example_test.go
@@ -0,0 +1,387 @@
+package toml_test
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "net/mail"
+ "time"
+
+ "github.com/BurntSushi/toml"
+)
+
+func ExampleEncoder_Encode() {
+ var (
+ date, _ = time.Parse(time.RFC822, "14 Mar 10 18:00 UTC")
+ buf = new(bytes.Buffer)
+ )
+ err := toml.NewEncoder(buf).Encode(map[string]interface{}{
+ "date": date,
+ "counts": []int{1, 1, 2, 3, 5, 8},
+ "hash": map[string]string{
+ "key1": "val1",
+ "key2": "val2",
+ },
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(buf.String())
+
+ // Output:
+ // counts = [1, 1, 2, 3, 5, 8]
+ // date = 2010-03-14T18:00:00Z
+ //
+ // [hash]
+ // key1 = "val1"
+ // key2 = "val2"
+}
+
+func ExampleMetaData_PrimitiveDecode() {
+ tomlBlob := `
+ ranking = ["Springsteen", "J Geils"]
+
+ [bands.Springsteen]
+ started = 1973
+ albums = ["Greetings", "WIESS", "Born to Run", "Darkness"]
+
+ [bands."J Geils"]
+ started = 1970
+ albums = ["The J. Geils Band", "Full House", "Blow Your Face Out"]
+ `
+
+ type (
+ band struct {
+ Started int
+ Albums []string
+ }
+ classics struct {
+ Ranking []string
+ Bands map[string]toml.Primitive
+ }
+ )
+
+ // Do the initial decode; reflection is delayed on Primitive values.
+ var music classics
+ md, err := toml.Decode(tomlBlob, &music)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // MetaData still includes information on Primitive values.
+ fmt.Printf("Is `bands.Springsteen` defined? %v\n",
+ md.IsDefined("bands", "Springsteen"))
+
+ // Decode primitive data into Go values.
+ for _, artist := range music.Ranking {
+ // A band is a primitive value, so we need to decode it to get a real
+ // `band` value.
+ primValue := music.Bands[artist]
+
+ var aBand band
+ err = md.PrimitiveDecode(primValue, &aBand)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("%s started in %d.\n", artist, aBand.Started)
+ }
+
+ // Check to see if there were any fields left undecoded. Note that this
+ // won't be empty before decoding the Primitive value!
+ fmt.Printf("Undecoded: %q\n", md.Undecoded())
+
+ // Output:
+ // Is `bands.Springsteen` defined? true
+ // Springsteen started in 1973.
+ // J Geils started in 1970.
+ // Undecoded: []
+}
+
+func ExampleDecode() {
+ tomlBlob := `
+ # Some comments.
+ [alpha]
+ ip = "10.0.0.1"
+
+ [alpha.config]
+ Ports = [ 8001, 8002 ]
+ Location = "Toronto"
+ Created = 1987-07-05T05:45:00Z
+
+ [beta]
+ ip = "10.0.0.2"
+
+ [beta.config]
+ Ports = [ 9001, 9002 ]
+ Location = "New Jersey"
+ Created = 1887-01-05T05:55:00Z
+ `
+
+ type (
+ serverConfig struct {
+ Ports []int
+ Location string
+ Created time.Time
+ }
+ server struct {
+ IP string `toml:"ip,omitempty"`
+ Config serverConfig `toml:"config"`
+ }
+ servers map[string]server
+ )
+
+ var config servers
+ _, err := toml.Decode(tomlBlob, &config)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, name := range []string{"alpha", "beta"} {
+ s := config[name]
+ fmt.Printf("Server: %s (ip: %s) in %s created on %s\n",
+ name, s.IP, s.Config.Location,
+ s.Config.Created.Format("2006-01-02"))
+ fmt.Printf("Ports: %v\n", s.Config.Ports)
+ }
+
+ // Output:
+ // Server: alpha (ip: 10.0.0.1) in Toronto created on 1987-07-05
+ // Ports: [8001 8002]
+ // Server: beta (ip: 10.0.0.2) in New Jersey created on 1887-01-05
+ // Ports: [9001 9002]
+}
+
+type address struct{ *mail.Address }
+
+func (a *address) UnmarshalText(text []byte) error {
+ var err error
+ a.Address, err = mail.ParseAddress(string(text))
+ return err
+}
+
+// Example Unmarshaler shows how to decode TOML strings into your own
+// custom data type.
+func Example_unmarshaler() {
+ blob := `
+ contacts = [
+ "Donald Duck <donald@duckburg.com>",
+ "Scrooge McDuck <scrooge@duckburg.com>",
+ ]
+ `
+
+ var contacts struct {
+ // Implementation of the address type:
+ //
+ // type address struct{ *mail.Address }
+ //
+ // func (a *address) UnmarshalText(text []byte) error {
+ // var err error
+ // a.Address, err = mail.ParseAddress(string(text))
+ // return err
+ // }
+
+ Contacts []address
+ }
+
+ _, err := toml.Decode(blob, &contacts)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, c := range contacts.Contacts {
+ fmt.Printf("%#v\n", c.Address)
+ }
+
+ // Output:
+ // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"}
+ // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"}
+}
+
+// Example StrictDecoding shows how to detect if there are keys in the TOML
+// document that weren't decoded into the value given. This is useful for
+// returning an error to the user if they've included extraneous fields in their
+// configuration.
+func Example_strictDecoding() {
+ var blob = `
+ key1 = "value1"
+ key2 = "value2"
+ key3 = "value3"
+ `
+
+ var conf struct {
+ Key1 string
+ Key3 string
+ }
+ md, err := toml.Decode(blob, &conf)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("Undecoded keys: %q\n", md.Undecoded())
+ // Output:
+ // Undecoded keys: ["key2"]
+}
+
+type order struct {
+ // NOTE `order.parts` is a private slice of type `part` which is an
+ // interface and may only be loaded from toml using the UnmarshalTOML()
+ // method of the Umarshaler interface.
+ parts parts
+}
+
+type parts []part
+
+type part interface {
+ Name() string
+}
+
+type valve struct {
+ Type string
+ ID string
+ Size float32
+ Rating int
+}
+
+func (v *valve) Name() string {
+ return fmt.Sprintf("VALVE: %s", v.ID)
+}
+
+type pipe struct {
+ Type string
+ ID string
+ Length float32
+ Diameter int
+}
+
+func (p *pipe) Name() string {
+ return fmt.Sprintf("PIPE: %s", p.ID)
+}
+
+type cable struct {
+ Type string
+ ID string
+ Length int
+ Rating float32
+}
+
+func (c *cable) Name() string {
+ return fmt.Sprintf("CABLE: %s", c.ID)
+}
+
+func (o *order) UnmarshalTOML(data interface{}) error {
+ // NOTE the example below contains detailed type casting to show how the
+ // 'data' is retrieved. In operational use, a type cast wrapper may be
+ // preferred e.g.
+ //
+ // func AsMap(v interface{}) (map[string]interface{}, error) {
+ // return v.(map[string]interface{})
+ // }
+ //
+ // resulting in:
+ // d, _ := AsMap(data)
+ //
+
+ d, _ := data.(map[string]interface{})
+ parts, _ := d["parts"].([]map[string]interface{})
+
+ for _, p := range parts {
+
+ typ, _ := p["type"].(string)
+ id, _ := p["id"].(string)
+
+ // detect the type of part and handle each case
+ switch p["type"] {
+ case "valve":
+
+ size := float32(p["size"].(float64))
+ rating := int(p["rating"].(int64))
+
+ valve := &valve{
+ Type: typ,
+ ID: id,
+ Size: size,
+ Rating: rating,
+ }
+
+ o.parts = append(o.parts, valve)
+
+ case "pipe":
+
+ length := float32(p["length"].(float64))
+ diameter := int(p["diameter"].(int64))
+
+ pipe := &pipe{
+ Type: typ,
+ ID: id,
+ Length: length,
+ Diameter: diameter,
+ }
+
+ o.parts = append(o.parts, pipe)
+
+ case "cable":
+
+ length := int(p["length"].(int64))
+ rating := float32(p["rating"].(float64))
+
+ cable := &cable{
+ Type: typ,
+ ID: id,
+ Length: length,
+ Rating: rating,
+ }
+
+ o.parts = append(o.parts, cable)
+
+ }
+ }
+
+ return nil
+}
+
+// Example UnmarshalTOML shows how to implement a struct type that knows how to
+// unmarshal itself. The struct must take full responsibility for mapping the
+// values passed into the struct. The method may be used with interfaces in a
+// struct in cases where the actual type is not known until the data is
+// examined.
+func Example_unmarshalTOML() {
+ blob := `
+ [[parts]]
+ type = "valve"
+ id = "valve-1"
+ size = 1.2
+ rating = 4
+
+ [[parts]]
+ type = "valve"
+ id = "valve-2"
+ size = 2.1
+ rating = 5
+
+ [[parts]]
+ type = "pipe"
+ id = "pipe-1"
+ length = 2.1
+ diameter = 12
+
+ [[parts]]
+ type = "cable"
+ id = "cable-1"
+ length = 12
+ rating = 3.1
+ `
+
+ // See example_test.go in the source for the implementation of the order
+ // type.
+ o := &order{}
+
+ err := toml.Unmarshal([]byte(blob), o)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(len(o.parts))
+ for _, part := range o.parts {
+ fmt.Println(part.Name())
+ }
+}