YAML in Go: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 17: Line 17:


import (
import (
  "fmt"
"fmt"
  "gopkg.in/yaml.v3"
"gopkg.in/yaml.v3"
  "os"
"os"
)
)


Line 34: Line 34:
//
//


type Root struct {
type Config struct {
  Color  string  `yaml:"color"`
Color  string  `yaml:"color"`
  Details Details `yaml:"details"`
Details Details `yaml:"details"`
}
}


type Details struct {
type Details struct {
  Size    int      `yaml:"size"`
Size    int      `yaml:"size"`
  Weight  float64  `yaml:"weight"`
Weight  float64  `yaml:"weight"`
  Used    bool    `yaml:"used"`
Used    bool    `yaml:"used"`
  Options []string `yaml:"options"`
Options []string `yaml:"options"`
}
}


Line 49: Line 49:
func main() {
func main() {


  root := Root{
config := Config{
    Color: "blue",
Color: "blue",
    Details: Details{
Details: Details{
        Size:    10,
Size:    10,
        Weight:  2.2,
Weight:  2.2,
        Used:    true,
Used:    true,
        Options: []string{"light", "medium", "heavy"},
Options: []string{"light", "medium", "heavy"},
    },
},
  }
}


  f, e := os.Create("/Users/ovidiu/tmp/test.yaml")
f, e := os.Create("/Users/ovidiu/tmp/test.yaml")
  if e != nil { ... }
if e != nil { ... }


  //
//
  // Marshal recursive memory struct into a file
// Marshal recursive memory struct into a file
  //
//


  if e := yaml.NewEncoder(f).Encode(&root); e != nil { ... }
if e := yaml.NewEncoder(f).Encode(&config); e != nil { ... }


  if e = f.Close(); e != nil { ... }
if e = f.Close(); e != nil { ... }
  fmt.Printf("yaml file written and closed\n")
fmt.Printf("yaml file written and closed\n")


  f, e = os.Open("/Users/ovidiu/tmp/test.yaml")
f, e = os.Open("/Users/ovidiu/tmp/test.yaml")
  if e != nil { ... }
if e != nil { ... }
  defer func() {
defer func() {
    if e = f.Close(); e != nil { ... }
if e = f.Close(); e != nil { ... }
  }()
}()


  //
//
  // Unmarshall the file into a different memory struct
// Unmarshall the file into a different memory struct
  //
//
  config2 := Root{}
config2 := Config{}
  if e = yaml.NewDecoder(f).Decode(&config2); e != nil { ... }
if e = yaml.NewDecoder(f).Decode(&config2); e != nil { ... }


  fmt.Printf("%+v\n", config2)
fmt.Printf("%+v\n", config2)
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 02:28, 5 January 2024

Internal

Overview

Declare a recursive structure that matches the structure of the YAML file, and then use a YAML encoder/decoder to marshall/unmarshall data in and out.

YAML support is available in the gopkg.in/yaml.v3 package.


If the structure fields are not capitalized, they are not visible across packages, and their content will zero-ed. The structure field will be accessible, but its content will be the corresponding zero value for the type.

Come up with an in-depth explanation for this.

package main

import (
	"fmt"
	"gopkg.in/yaml.v3"
	"os"
)

//
// color: "blue:
// details:
//   size: 10
//   weight 2.2
//   used: true
//   options:
//     - light
//     - medium
//     - heavy
//

type Config struct {
	Color   string  `yaml:"color"`
	Details Details `yaml:"details"`
}

type Details struct {
	Size    int      `yaml:"size"`
	Weight  float64  `yaml:"weight"`
	Used    bool     `yaml:"used"`
	Options []string `yaml:"options"`
}


func main() {

	config := Config{
		Color: "blue",
		Details: Details{
			Size:    10,
			Weight:  2.2,
			Used:    true,
			Options: []string{"light", "medium", "heavy"},
		},
	}

	f, e := os.Create("/Users/ovidiu/tmp/test.yaml")
	if e != nil { ... }

	//
	// Marshal recursive memory struct into a file
	//

	if e := yaml.NewEncoder(f).Encode(&config); e != nil { ... }

	if e = f.Close(); e != nil { ... }
	fmt.Printf("yaml file written and closed\n")

	f, e = os.Open("/Users/ovidiu/tmp/test.yaml")
	if e != nil { ... }
	defer func() {
		if e = f.Close(); e != nil { ... }
	}()

	//
	// Unmarshall the file into a different memory struct
	//
	config2 := Config{}
	if e = yaml.NewDecoder(f).Decode(&config2); e != nil { ... }

	fmt.Printf("%+v\n", config2)
}