cuelang.org/go@v0.10.1/internal/third_party/yaml/yaml.go (about) 1 // Package yaml implements YAML support for the Go language. 2 // 3 // Source code and other details for the project are available at GitHub: 4 // 5 // https://github.com/go-yaml/yaml 6 package yaml 7 8 import ( 9 "fmt" 10 "io" 11 "strconv" 12 "strings" 13 14 "cuelang.org/go/cue/ast" 15 ) 16 17 // Unmarshal decodes the first document found within the in byte slice 18 // and returns it as a CUE syntax AST. 19 func Unmarshal(filename string, in []byte) (expr ast.Expr, err error) { 20 return unmarshal(filename, in) 21 } 22 23 // A Decoder reads and decodes YAML values from an input stream. 24 type Decoder struct { 25 strict bool 26 firstDone bool 27 parser *parser 28 } 29 30 // NewDecoder returns a new decoder that reads from r. 31 // 32 // The decoder introduces its own buffering and may read 33 // data from r beyond the YAML values requested. 34 func NewDecoder(filename string, src interface{}) (*Decoder, error) { 35 d, err := newParser(filename, src) 36 if err != nil { 37 return nil, err 38 } 39 return &Decoder{parser: d}, nil 40 } 41 42 // Decode reads the next YAML-encoded value from its input and returns 43 // it as CUE syntax. It returns io.EOF if there are no more value in the 44 // stream. 45 func (dec *Decoder) Decode() (expr ast.Expr, err error) { 46 d := newDecoder(dec.parser) 47 defer handleErr(&err) 48 node := dec.parser.parse() 49 if node == nil { 50 if !dec.firstDone { 51 expr = ast.NewNull() 52 } 53 return expr, io.EOF 54 } 55 dec.firstDone = true 56 expr = d.unmarshal(node) 57 if len(d.terrors) > 0 { 58 return nil, &TypeError{d.terrors} 59 } 60 return expr, nil 61 } 62 63 func unmarshal(filename string, in []byte) (expr ast.Expr, err error) { 64 defer handleErr(&err) 65 p, err := newParser(filename, in) 66 if err != nil { 67 return nil, err 68 } 69 defer p.destroy() 70 node := p.parse() 71 d := newDecoder(p) 72 if node != nil { 73 expr = d.unmarshal(node) 74 } 75 if len(d.terrors) > 0 { 76 return nil, &TypeError{d.terrors} 77 } 78 return expr, nil 79 } 80 81 func handleErr(err *error) { 82 if v := recover(); v != nil { 83 if e, ok := v.(yamlError); ok { 84 *err = e.err 85 } else { 86 panic(v) 87 } 88 } 89 } 90 91 type yamlError struct { 92 err error 93 } 94 95 func (p *parser) failf(line int, format string, args ...interface{}) { 96 where := p.parser.filename + ":" 97 line++ 98 where += strconv.Itoa(line) + ": " 99 panic(yamlError{fmt.Errorf(where+format, args...)}) 100 } 101 102 // A TypeError is returned by Unmarshal when one or more fields in 103 // the YAML document cannot be properly decoded into the requested 104 // types. When this error is returned, the value is still 105 // unmarshaled partially. 106 type TypeError struct { 107 Errors []string 108 } 109 110 func (e *TypeError) Error() string { 111 return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) 112 }