]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/zclconf/go-cty/cty/helper.go
update vendor and go.mod
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / zclconf / go-cty / cty / helper.go
1 package cty
2
3 import (
4 "fmt"
5 )
6
7 // anyUnknown is a helper to easily check if a set of values contains any
8 // unknowns, for operations that short-circuit to return unknown in that case.
9 func anyUnknown(values ...Value) bool {
10 for _, val := range values {
11 if val.v == unknown {
12 return true
13 }
14 }
15 return false
16 }
17
18 // typeCheck tests whether all of the given values belong to the given type.
19 // If the given types are a mixture of the given type and the dynamic
20 // pseudo-type then a short-circuit dynamic value is returned. If the given
21 // values are all of the correct type but at least one is unknown then
22 // a short-circuit unknown value is returned. If any other types appear then
23 // an error is returned. Otherwise (finally!) the result is nil, nil.
24 func typeCheck(required Type, ret Type, values ...Value) (shortCircuit *Value, err error) {
25 hasDynamic := false
26 hasUnknown := false
27
28 for i, val := range values {
29 if val.ty == DynamicPseudoType {
30 hasDynamic = true
31 continue
32 }
33
34 if !val.Type().Equals(required) {
35 return nil, fmt.Errorf(
36 "type mismatch: want %s but value %d is %s",
37 required.FriendlyName(),
38 i, val.ty.FriendlyName(),
39 )
40 }
41
42 if val.v == unknown {
43 hasUnknown = true
44 }
45 }
46
47 if hasDynamic {
48 return &DynamicVal, nil
49 }
50
51 if hasUnknown {
52 ret := UnknownVal(ret)
53 return &ret, nil
54 }
55
56 return nil, nil
57 }
58
59 // mustTypeCheck is a wrapper around typeCheck that immediately panics if
60 // any error is returned.
61 func mustTypeCheck(required Type, ret Type, values ...Value) *Value {
62 shortCircuit, err := typeCheck(required, ret, values...)
63 if err != nil {
64 panic(err)
65 }
66 return shortCircuit
67 }
68
69 // shortCircuitForceType takes the return value from mustTypeCheck and
70 // replaces it with an unknown of the given type if the original value was
71 // DynamicVal.
72 //
73 // This is useful for operations that are specified to always return a
74 // particular type, since then a dynamic result can safely be "upgrade" to
75 // a strongly-typed unknown, which then allows subsequent operations to
76 // be actually type-checked.
77 //
78 // It is safe to use this only if the operation in question is defined as
79 // returning either a value of the given type or panicking, since we know
80 // then that subsequent operations won't run if the operation panics.
81 //
82 // If the given short-circuit value is *not* DynamicVal then it must be
83 // of the given type, or this function will panic.
84 func forceShortCircuitType(shortCircuit *Value, ty Type) *Value {
85 if shortCircuit == nil {
86 return nil
87 }
88
89 if shortCircuit.ty == DynamicPseudoType {
90 ret := UnknownVal(ty)
91 return &ret
92 }
93
94 if !shortCircuit.ty.Equals(ty) {
95 panic("forceShortCircuitType got value of wrong type")
96 }
97
98 return shortCircuit
99 }