yaml

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2024 License: Apache-2.0, MIT Imports: 18 Imported by: 1

README

YAML support for the Go language

Changes for DIMO


Reason to fork this is to add support for custom types we use often in our services. To add a custom type, edit the decoder.go file under the reflect.Kind case of the scalar function.

Introduction

The yaml package enables Go programs to comfortably encode and decode YAML values. It was developed within Canonical as part of the juju project, and is based on a pure Go port of the well-known libyaml C library to parse and generate YAML data quickly and reliably.

Compatibility

The yaml package supports most of YAML 1.2, but preserves some behavior from 1.1 for backwards compatibility.

Specifically, as of v3 of the yaml package:

  • YAML 1.1 bools (yes/no, on/off) are supported as long as they are being decoded into a typed bool value. Otherwise they behave as a string. Booleans in YAML 1.2 are true/false only.
  • Octals encode and decode as 0777 per YAML 1.1, rather than 0o777 as specified in YAML 1.2, because most parsers still use the old format. Octals in the 0o777 format are supported though, so new files work.
  • Does not support base-60 floats. These are gone from YAML 1.2, and were actually never supported by this package as it's clearly a poor choice.

and offers backwards compatibility with YAML 1.1 in some cases. 1.2, including support for anchors, tags, map merging, etc. Multi-document unmarshalling is not yet implemented, and base-60 floats from YAML 1.1 are purposefully not supported since they're a poor design and are gone in YAML 1.2.

Installation and usage

The import path for the package is gopkg.in/yaml.v3.

To install it, run:

go get gopkg.in/yaml.v3

API documentation

If opened in a browser, the import path itself leads to the API documentation:

API stability

The package API for yaml v3 will remain stable as described in gopkg.in.

License

The yaml package is licensed under the MIT and Apache License 2.0 licenses. Please see the LICENSE file for details.

Example

package main

import (
        "fmt"
        "log"

        "gopkg.in/yaml.v3"
)

var data = `
a: Easy!
b:
  c: 2
  d: [3, 4]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
        A string
        B struct {
                RenamedC int   `yaml:"c"`
                D        []int `yaml:",flow"`
        }
}

func main() {
        t := T{}
    
        err := yaml.Unmarshal([]byte(data), &t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t:\n%v\n\n", t)
    
        d, err := yaml.Marshal(&t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t dump:\n%s\n\n", string(d))
    
        m := make(map[interface{}]interface{})
    
        err = yaml.Unmarshal([]byte(data), &m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m:\n%v\n\n", m)
    
        d, err = yaml.Marshal(&m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m dump:\n%s\n\n", string(d))
}

This example will generate the following output:

--- t:
{Easy! {2 [3 4]}}

--- t dump:
a: Easy!
b:
  c: 2
  d: [3, 4]


--- m:
map[a:Easy! b:map[c:2 d:[3 4]]]

--- m dump:
a: Easy!
b:
  c: 2
  d:
  - 3
  - 4

Documentation

Overview

Package yaml implements YAML support for the Go language.

Source code and other details for the project are available at GitHub:

https://github.com/go-yaml/yaml

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(in interface{}) (out []byte, err error)

Marshal serializes the value provided into a YAML document. The structure of the generated document will reflect the structure of the value itself. Maps and pointers (to struct, string, int, etc) are accepted as the in value.

Struct fields are only marshalled if they are exported (have an upper case first letter), and are marshalled using the field name lowercased as the default key. Custom keys may be defined via the "yaml" name in the field tag: the content preceding the first comma is used as the key, and the following comma-separated options are used to tweak the marshalling process. Conflicting names result in a runtime error.

The field tag format accepted is:

`(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`

The following flags are currently supported:

omitempty    Only include the field if it's not set to the zero
             value for the type or to empty slices or maps.
             Zero valued structs will be omitted if all their public
             fields are zero, unless they implement an IsZero
             method (see the IsZeroer interface type), in which
             case the field will be excluded if IsZero returns true.

flow         Marshal using a flow style (useful for structs,
             sequences and maps).

inline       Inline the field, which must be a struct or a map,
             causing all of its fields or keys to be processed as if
             they were part of the outer struct. For maps, keys must
             not conflict with the yaml keys of other struct fields.

In addition, if the key is "-", the field is ignored.

For example:

type T struct {
    F int `yaml:"a,omitempty"`
    B int
}
yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"

func Unmarshal

func Unmarshal(in []byte, out interface{}) (err error)

Unmarshal decodes the first document found within the in byte slice and assigns decoded values into the out value.

Maps and pointers (to a struct, string, int, etc) are accepted as out values. If an internal pointer within a struct is not initialized, the yaml package will initialize it if necessary for unmarshalling the provided data. The out parameter must not be nil.

The type of the decoded values should be compatible with the respective values in out. If one or more values cannot be decoded due to a type mismatches, decoding continues partially until the end of the YAML content, and a *yaml.TypeError is returned with details for all missed values.

Struct fields are only unmarshalled if they are exported (have an upper case first letter), and are unmarshalled using the field name lowercased as the default key. Custom keys may be defined via the "yaml" name in the field tag: the content preceding the first comma is used as the key, and the following comma-separated options are used to tweak the marshalling process (see Marshal). Conflicting names result in a runtime error.

For example:

type T struct {
    F int `yaml:"a,omitempty"`
    B int
}
var t T
yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)

See the documentation of Marshal for the format of tags and a list of supported tag options.

Example (Embedded)
package main

import (
	"fmt"
	"log"

	"gopkg.in/yaml.v3"
)

// An example showing how to unmarshal embedded
// structs from YAML.

type StructA struct {
	A string `yaml:"a"`
}

type StructB struct {
	// Embedded structs are not treated as embedded in YAML by default. To do that,
	// add the ",inline" annotation below
	StructA `yaml:",inline"`
	B       string `yaml:"b"`
}

var data = `
a: a string from struct A
b: a string from struct B
`

func main() {
	var b StructB

	err := yaml.Unmarshal([]byte(data), &b)
	if err != nil {
		log.Fatalf("cannot unmarshal data: %v", err)
	}
	fmt.Println(b.A)
	fmt.Println(b.B)
}
Output:

a string from struct A
a string from struct B

Types

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

A Decoder reads and decodes YAML values from an input stream.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder returns a new decoder that reads from r.

The decoder introduces its own buffering and may read data from r beyond the YAML values requested.

func (*Decoder) Decode

func (dec *Decoder) Decode(v interface{}) (err error)

Decode reads the next YAML-encoded value from its input and stores it in the value pointed to by v.

See the documentation for Unmarshal for details about the conversion of YAML into a Go value.

func (*Decoder) KnownFields

func (dec *Decoder) KnownFields(enable bool)

KnownFields ensures that the keys in decoded mappings to exist as fields in the struct being decoded into.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

An Encoder writes YAML values to an output stream.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns a new encoder that writes to w. The Encoder should be closed after use to flush all data to w.

func (*Encoder) Close

func (e *Encoder) Close() (err error)

Close closes the encoder by writing any remaining data. It does not write a stream terminating string "...".

func (*Encoder) Encode

func (e *Encoder) Encode(v interface{}) (err error)

Encode writes the YAML encoding of v to the stream. If multiple items are encoded to the stream, the second and subsequent document will be preceded with a "---" document separator, but the first will not.

See the documentation for Marshal for details about the conversion of Go values to YAML.

func (*Encoder) SetIndent

func (e *Encoder) SetIndent(spaces int)

SetIndent changes the used indentation used when encoding.

type IsZeroer

type IsZeroer interface {
	IsZero() bool
}

IsZeroer is used to check whether an object is zero to determine whether it should be omitted when marshaling with the omitempty flag. One notable implementation is time.Time.

type Kind

type Kind uint32
const (
	DocumentNode Kind = 1 << iota
	SequenceNode
	MappingNode
	ScalarNode
	AliasNode
)

type Marshaler

type Marshaler interface {
	MarshalYAML() (interface{}, error)
}

The Marshaler interface may be implemented by types to customize their behavior when being marshaled into a YAML document. The returned value is marshaled in place of the original value implementing Marshaler.

If an error is returned by MarshalYAML, the marshaling procedure stops and returns with the provided error.

type Node

type Node struct {
	// Kind defines whether the node is a document, a mapping, a sequence,
	// a scalar value, or an alias to another node. The specific data type of
	// scalar nodes may be obtained via the ShortTag and LongTag methods.
	Kind Kind

	// Style allows customizing the apperance of the node in the tree.
	Style Style

	// Tag holds the YAML tag defining the data type for the value.
	// When decoding, this field will always be set to the resolved tag,
	// even when it wasn't explicitly provided in the YAML content.
	// When encoding, if this field is unset the value type will be
	// implied from the node properties, and if it is set, it will only
	// be serialized into the representation if TaggedStyle is used or
	// the implicit tag diverges from the provided one.
	Tag string

	// Value holds the unescaped and unquoted represenation of the value.
	Value string

	// Anchor holds the anchor name for this node, which allows aliases to point to it.
	Anchor string

	// Alias holds the node that this alias points to. Only valid when Kind is AliasNode.
	Alias *Node

	// Content holds contained nodes for documents, mappings, and sequences.
	Content []*Node

	// HeadComment holds any comments in the lines preceding the node and
	// not separated by an empty line.
	HeadComment string

	// LineComment holds any comments at the end of the line where the node is in.
	LineComment string

	// FootComment holds any comments following the node and before empty lines.
	FootComment string

	// Line and Column hold the node position in the decoded YAML text.
	// These fields are not respected when encoding the node.
	Line   int
	Column int
}

Node represents an element in the YAML document hierarchy. While documents are typically encoded and decoded into higher level types, such as structs and maps, Node is an intermediate representation that allows detailed control over the content being decoded or encoded.

It's worth noting that although Node offers access into details such as line numbers, colums, and comments, the content when re-encoded will not have its original textual representation preserved. An effort is made to render the data plesantly, and to preserve comments near the data they describe, though.

Values that make use of the Node type interact with the yaml package in the same way any other type would do, by encoding and decoding yaml data directly or indirectly into them.

For example:

var person struct {
        Name    string
        Address yaml.Node
}
err := yaml.Unmarshal(data, &person)

Or by itself:

var person Node
err := yaml.Unmarshal(data, &person)

func (*Node) Decode

func (n *Node) Decode(v interface{}) (err error)

Decode decodes the node and stores its data into the value pointed to by v.

See the documentation for Unmarshal for details about the conversion of YAML into a Go value.

func (*Node) Encode

func (n *Node) Encode(v interface{}) (err error)

Encode encodes value v and stores its representation in n.

See the documentation for Marshal for details about the conversion of Go values into YAML.

func (*Node) IsZero

func (n *Node) IsZero() bool

IsZero returns whether the node has all of its fields unset.

func (*Node) LongTag

func (n *Node) LongTag() string

LongTag returns the long form of the tag that indicates the data type for the node. If the Tag field isn't explicitly defined, one will be computed based on the node properties.

func (*Node) SetString

func (n *Node) SetString(s string)

SetString is a convenience function that sets the node to a string value and defines its style in a pleasant way depending on its content.

func (*Node) ShortTag

func (n *Node) ShortTag() string

ShortTag returns the short form of the YAML tag that indicates data type for the node. If the Tag field isn't explicitly defined, one will be computed based on the node properties.

type Style

type Style uint32
const (
	TaggedStyle Style = 1 << iota
	DoubleQuotedStyle
	SingleQuotedStyle
	LiteralStyle
	FoldedStyle
	FlowStyle
)

type TypeError

type TypeError struct {
	Errors []string
}

A TypeError is returned by Unmarshal when one or more fields in the YAML document cannot be properly decoded into the requested types. When this error is returned, the value is still unmarshaled partially.

func (*TypeError) Error

func (e *TypeError) Error() string

type Unmarshaler

type Unmarshaler interface {
	UnmarshalYAML(value *Node) error
}

The Unmarshaler interface may be implemented by types to customize their behavior when being unmarshaled from a YAML document.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL