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  }