cuelang.org/go@v0.13.0/internal/value/value.go (about)

     1  // Copyright 2021 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 value contains functions for converting values to internal types
    16  // and various other Value-related utilities.
    17  package value
    18  
    19  import (
    20  	"strings"
    21  
    22  	"cuelang.org/go/cue"
    23  	"cuelang.org/go/internal/core/adt"
    24  	"cuelang.org/go/internal/core/convert"
    25  	"cuelang.org/go/internal/core/eval"
    26  	"cuelang.org/go/internal/core/runtime"
    27  	"cuelang.org/go/internal/types"
    28  )
    29  
    30  // Context returns the cue.Context of the given argument.
    31  func Context[Ctx *cue.Runtime | *cue.Context | cue.Value | *adt.OpContext](ctx Ctx) *cue.Context {
    32  	switch x := any(ctx).(type) {
    33  	case *cue.Runtime:
    34  		(*runtime.Runtime)(x).Init()
    35  		return (*cue.Context)(x)
    36  	case *cue.Context:
    37  		return x
    38  	case cue.Value:
    39  		r, _ := ToInternal(x)
    40  		return (*cue.Context)(r)
    41  	case *adt.OpContext:
    42  		r := x.Runtime.(*runtime.Runtime)
    43  		return (*cue.Context)(r)
    44  	}
    45  	panic("unreachable")
    46  }
    47  
    48  // OpContext returns an OpContext with proper node formatting initialized.
    49  func OpContext[Ctx *cue.Runtime | *cue.Context | cue.Value](c Ctx) *adt.OpContext {
    50  	var r *runtime.Runtime
    51  	var v *adt.Vertex
    52  	switch x := any(c).(type) {
    53  	case *cue.Runtime:
    54  		r = (*runtime.Runtime)(x)
    55  		r.Init()
    56  	case *cue.Context:
    57  		r = (*runtime.Runtime)(x)
    58  	case cue.Value:
    59  		r, v = ToInternal(x)
    60  	default:
    61  		panic("unreachable")
    62  	}
    63  	return eval.NewContext(r, v)
    64  }
    65  
    66  func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) {
    67  	var t types.Value
    68  	v.Core(&t)
    69  	return t.R, t.V
    70  }
    71  
    72  func Vertex(v cue.Value) *adt.Vertex {
    73  	var t types.Value
    74  	v.Core(&t)
    75  	return t.V
    76  }
    77  
    78  // Make wraps cue.MakeValue.
    79  func Make(ctx *adt.OpContext, v adt.Value) cue.Value {
    80  	return Context(ctx).Encode(v)
    81  }
    82  
    83  // UnifyBuiltin returns the given Value unified with the given builtin template.
    84  func UnifyBuiltin(v cue.Value, kind string) cue.Value {
    85  	pkg, name, _ := strings.Cut(kind, ".")
    86  	s := runtime.SharedRuntime().LoadImport(pkg)
    87  	if s == nil {
    88  		return v
    89  	}
    90  
    91  	ctx := v.Context()
    92  	a := s.Lookup((*runtime.Runtime)(ctx).Label(name, false))
    93  	if a == nil {
    94  		return v
    95  	}
    96  
    97  	return v.Unify(ctx.Encode(a))
    98  }
    99  
   100  func FromGoValue(r *cue.Context, x interface{}, nilIsTop bool) cue.Value {
   101  	rt := (*runtime.Runtime)(r)
   102  	rt.Init()
   103  	ctx := eval.NewContext(rt, nil)
   104  	v := convert.GoValueToValue(ctx, x, nilIsTop)
   105  	n := adt.ToVertex(v)
   106  	return r.Encode(n)
   107  }
   108  
   109  func FromGoType(r *cue.Context, x interface{}) cue.Value {
   110  	rt := (*runtime.Runtime)(r)
   111  	rt.Init()
   112  	ctx := eval.NewContext(rt, nil)
   113  	expr, err := convert.GoTypeToExpr(ctx, x)
   114  	if err != nil {
   115  		expr = &adt.Bottom{Err: err}
   116  	}
   117  	n := &adt.Vertex{}
   118  	n.AddConjunct(adt.MakeRootConjunct(nil, expr))
   119  	return r.Encode(n)
   120  }