mirror of
https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git
synced 2024-11-18 15:58:12 +00:00
133 lines
5.5 KiB
Go
133 lines
5.5 KiB
Go
|
package cty
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
// CapsuleOps represents a set of overloaded operations for a capsule type.
|
||
|
//
|
||
|
// Each field is a reference to a function that can either be nil or can be
|
||
|
// set to an implementation of the corresponding operation. If an operation
|
||
|
// function is nil then it isn't supported for the given capsule type.
|
||
|
type CapsuleOps struct {
|
||
|
// GoString provides the GoString implementation for values of the
|
||
|
// corresponding type. Conventionally this should return a string
|
||
|
// representation of an expression that would produce an equivalent
|
||
|
// value.
|
||
|
GoString func(val interface{}) string
|
||
|
|
||
|
// TypeGoString provides the GoString implementation for the corresponding
|
||
|
// capsule type itself.
|
||
|
TypeGoString func(goTy reflect.Type) string
|
||
|
|
||
|
// Equals provides the implementation of the Equals operation. This is
|
||
|
// called only with known, non-null values of the corresponding type,
|
||
|
// but if the corresponding type is a compound type then it must be
|
||
|
// ready to detect and handle nested unknown or null values, usually
|
||
|
// by recursively calling Value.Equals on those nested values.
|
||
|
//
|
||
|
// The result value must always be of type cty.Bool, or the Equals
|
||
|
// operation will panic.
|
||
|
//
|
||
|
// If RawEquals is set without also setting Equals, the RawEquals
|
||
|
// implementation will be used as a fallback implementation. That fallback
|
||
|
// is appropriate only for leaf types that do not contain any nested
|
||
|
// cty.Value that would need to distinguish Equals vs. RawEquals for their
|
||
|
// own equality.
|
||
|
//
|
||
|
// If RawEquals is nil then Equals must also be nil, selecting the default
|
||
|
// pointer-identity comparison instead.
|
||
|
Equals func(a, b interface{}) Value
|
||
|
|
||
|
// RawEquals provides the implementation of the RawEquals operation.
|
||
|
// This is called only with known, non-null values of the corresponding
|
||
|
// type, but if the corresponding type is a compound type then it must be
|
||
|
// ready to detect and handle nested unknown or null values, usually
|
||
|
// by recursively calling Value.RawEquals on those nested values.
|
||
|
//
|
||
|
// If RawEquals is nil, values of the corresponding type are compared by
|
||
|
// pointer identity of the encapsulated value.
|
||
|
RawEquals func(a, b interface{}) bool
|
||
|
|
||
|
// ConversionFrom can provide conversions from the corresponding type to
|
||
|
// some other type when values of the corresponding type are used with
|
||
|
// the "convert" package. (The main cty package does not use this operation.)
|
||
|
//
|
||
|
// This function itself returns a function, allowing it to switch its
|
||
|
// behavior depending on the given source type. Return nil to indicate
|
||
|
// that no such conversion is available.
|
||
|
ConversionFrom func(src Type) func(interface{}, Path) (Value, error)
|
||
|
|
||
|
// ConversionTo can provide conversions to the corresponding type from
|
||
|
// some other type when values of the corresponding type are used with
|
||
|
// the "convert" package. (The main cty package does not use this operation.)
|
||
|
//
|
||
|
// This function itself returns a function, allowing it to switch its
|
||
|
// behavior depending on the given destination type. Return nil to indicate
|
||
|
// that no such conversion is available.
|
||
|
ConversionTo func(dst Type) func(Value, Path) (interface{}, error)
|
||
|
|
||
|
// ExtensionData is an extension point for applications that wish to
|
||
|
// create their own extension features using capsule types.
|
||
|
//
|
||
|
// The key argument is any value that can be compared with Go's ==
|
||
|
// operator, but should be of a named type in a package belonging to the
|
||
|
// application defining the key. An ExtensionData implementation must
|
||
|
// check to see if the given key is familar to it, and if so return a
|
||
|
// suitable value for the key.
|
||
|
//
|
||
|
// If the given key is unrecognized, the ExtensionData function must
|
||
|
// return a nil interface. (Importantly, not an interface containing a nil
|
||
|
// pointer of some other type.)
|
||
|
// The common implementation of ExtensionData is a single switch statement
|
||
|
// over "key" which has a default case returning nil.
|
||
|
//
|
||
|
// The meaning of any given key is entirely up to the application that
|
||
|
// defines it. Applications consuming ExtensionData from capsule types
|
||
|
// should do so defensively: if the result of ExtensionData is not valid,
|
||
|
// prefer to ignore it or gracefully produce an error rather than causing
|
||
|
// a panic.
|
||
|
ExtensionData func(key interface{}) interface{}
|
||
|
}
|
||
|
|
||
|
// noCapsuleOps is a pointer to a CapsuleOps with no functions set, which
|
||
|
// is used as the default operations value when a type is created using
|
||
|
// the Capsule function.
|
||
|
var noCapsuleOps = &CapsuleOps{}
|
||
|
|
||
|
func (ops *CapsuleOps) assertValid() {
|
||
|
if ops.RawEquals == nil && ops.Equals != nil {
|
||
|
panic("Equals cannot be set without RawEquals")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// CapsuleOps returns a pointer to the CapsuleOps value for a capsule type,
|
||
|
// or panics if the receiver is not a capsule type.
|
||
|
//
|
||
|
// The caller must not modify the CapsuleOps.
|
||
|
func (ty Type) CapsuleOps() *CapsuleOps {
|
||
|
if !ty.IsCapsuleType() {
|
||
|
panic("not a capsule-typed value")
|
||
|
}
|
||
|
|
||
|
return ty.typeImpl.(*capsuleType).Ops
|
||
|
}
|
||
|
|
||
|
// CapsuleExtensionData is a convenience interface to the ExtensionData
|
||
|
// function that can be optionally implemented for a capsule type. It will
|
||
|
// check to see if the underlying type implements ExtensionData and call it
|
||
|
// if so. If not, it will return nil to indicate that the given key is not
|
||
|
// supported.
|
||
|
//
|
||
|
// See the documentation for CapsuleOps.ExtensionData for more information
|
||
|
// on the purpose of and usage of this mechanism.
|
||
|
//
|
||
|
// If CapsuleExtensionData is called on a non-capsule type then it will panic.
|
||
|
func (ty Type) CapsuleExtensionData(key interface{}) interface{} {
|
||
|
ops := ty.CapsuleOps()
|
||
|
if ops.ExtensionData == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return ops.ExtensionData(key)
|
||
|
}
|