github.com/solo-io/cue@v0.4.7/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 "github.com/solo-io/cue/cue" 24 "github.com/solo-io/cue/cue/ast" 25 cueyaml "github.com/solo-io/cue/internal/encoding/yaml" 26 "github.com/solo-io/cue/internal/third_party/yaml" 27 pkgyaml "github.com/solo-io/cue/pkg/encoding/yaml" 28 ) 29 30 // Extract parses the YAML to a CUE expression. Streams are returned as a list 31 // of the streamed values. 32 func Extract(filename string, src interface{}) (*ast.File, error) { 33 a := []ast.Expr{} 34 d, err := yaml.NewDecoder(filename, src) 35 if err != nil { 36 return nil, err 37 } 38 for { 39 expr, err := d.Decode() 40 if err != nil { 41 if err != io.EOF { 42 return nil, err 43 } 44 if expr != nil { 45 a = append(a, expr) 46 } 47 break 48 } 49 a = append(a, expr) 50 } 51 f := &ast.File{Filename: filename} 52 switch len(a) { 53 case 0: 54 case 1: 55 switch x := a[0].(type) { 56 case *ast.StructLit: 57 f.Decls = x.Elts 58 default: 59 f.Decls = []ast.Decl{&ast.EmbedDecl{Expr: x}} 60 } 61 default: 62 f.Decls = []ast.Decl{&ast.EmbedDecl{Expr: &ast.ListLit{Elts: a}}} 63 } 64 return f, nil 65 } 66 67 // Decode converts a YAML file to a CUE value. Streams are returned as a list 68 // of the streamed values. 69 // 70 // Deprecate: use Extract and build the File with cue.Context.BuildFile. 71 func Decode(r *cue.Runtime, filename string, src interface{}) (*cue.Instance, error) { 72 file, err := Extract(filename, src) 73 if err != nil { 74 return nil, err 75 } 76 return r.CompileFile(file) 77 } 78 79 // Encode returns the YAML encoding of v. 80 func Encode(v cue.Value) ([]byte, error) { 81 n := v.Syntax(cue.Final()) 82 b, err := cueyaml.Encode(n) 83 return b, err 84 } 85 86 // EncodeStream returns the YAML encoding of iter, where consecutive values 87 // of iter are separated with a `---`. 88 func EncodeStream(iter cue.Iterator) ([]byte, error) { 89 // TODO: return an io.Reader and allow asynchronous processing. 90 buf := &bytes.Buffer{} 91 for i := 0; iter.Next(); i++ { 92 if i > 0 { 93 buf.WriteString("---\n") 94 } 95 n := iter.Value().Syntax(cue.Final()) 96 b, err := cueyaml.Encode(n) 97 if err != nil { 98 return nil, err 99 } 100 buf.Write(b) 101 } 102 return buf.Bytes(), nil 103 } 104 105 // Validate validates the YAML and confirms it matches the constraints 106 // specified by v. For YAML streams, all values must match v. 107 func Validate(b []byte, v cue.Value) error { 108 _, err := pkgyaml.Validate(b, v) 109 return err 110 }