diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 17:02:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 17:02:14 +0000 |
commit | e61c5fa98419989a61b5ca4eb7749acbd37e0af6 (patch) | |
tree | ffe04b0283921bd40489aaa74dcee1f68b7b6b35 /example_test.go | |
parent | Initial commit. (diff) | |
download | golang-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.go | 387 |
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()) + } +} |