cuelang.org/go@v0.13.0/encoding/yaml/yaml.go (about) 1 // Copyright 2019 The CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package yaml converts YAML encodings to and from CUE. When converting to CUE, 16 // comments and position information are retained. 17 package yaml 18 19 import ( 20 "bytes" 21 "io" 22 23 "cuelang.org/go/cue" 24 "cuelang.org/go/cue/ast" 25 cueyaml "cuelang.org/go/internal/encoding/yaml" 26 "cuelang.org/go/internal/source" 27 "cuelang.org/go/internal/value" 28 ) 29 30 // Extract parses the YAML specified by src to a CUE expression. If 31 // there's more than one document, the documents will be returned as a 32 // list. The src argument may be a nil, string, []byte, or io.Reader. If 33 // src is nil, the result of reading the file specified by filename will 34 // be used. 35 func Extract(filename string, src interface{}) (*ast.File, error) { 36 data, err := source.ReadAll(filename, src) 37 if err != nil { 38 return nil, err 39 } 40 a := []ast.Expr{} 41 d := cueyaml.NewDecoder(filename, data) 42 for { 43 expr, err := d.Decode() 44 if err != nil { 45 if err != io.EOF { 46 return nil, err 47 } 48 if expr != nil { 49 a = append(a, expr) 50 } 51 break 52 } 53 a = append(a, expr) 54 } 55 f := &ast.File{Filename: filename} 56 switch len(a) { 57 case 0: 58 case 1: 59 switch x := a[0].(type) { 60 case *ast.StructLit: 61 f.Decls = x.Elts 62 default: 63 f.Decls = []ast.Decl{&ast.EmbedDecl{Expr: x}} 64 } 65 default: 66 f.Decls = []ast.Decl{&ast.EmbedDecl{Expr: &ast.ListLit{Elts: a}}} 67 } 68 return f, nil 69 } 70 71 // Encode returns the YAML encoding of v. 72 func Encode(v cue.Value) ([]byte, error) { 73 n := v.Syntax(cue.Final()) 74 b, err := cueyaml.Encode(n) 75 return b, err 76 } 77 78 // EncodeStream returns the YAML encoding of iter, where consecutive values 79 // of iter are separated with a `---`. 80 func EncodeStream(iter cue.Iterator) ([]byte, error) { 81 // TODO: return an io.Reader and allow asynchronous processing. 82 buf := &bytes.Buffer{} 83 for i := 0; iter.Next(); i++ { 84 if i > 0 { 85 buf.WriteString("---\n") 86 } 87 n := iter.Value().Syntax(cue.Final()) 88 b, err := cueyaml.Encode(n) 89 if err != nil { 90 return nil, err 91 } 92 buf.Write(b) 93 } 94 return buf.Bytes(), nil 95 } 96 97 // Validate validates the YAML and confirms it matches the constraints 98 // specified by v. For YAML streams, all values must match v. 99 func Validate(b []byte, v cue.Value) error { 100 ctx := value.OpContext(v) 101 _, err := cueyaml.Validate(ctx, b, v) 102 return err 103 }