encapsulator

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Type-safe conversions to and from cty.CapsuleValue

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNullVal    = errors.New("null value")
	ErrUnknownVal = errors.New("unknown value")
	ErrWrongType  = errors.New("wrong type")
)

Functions

func Compatible

func Compatible(encoder EncoderI, decoder DecoderI) bool

Compatible checks that values produced by the given Encoder are decodable by the given Decoder. This is a loose check, for example it allows decoding value that implements interface DT.

Types

type CapsuleOps

type CapsuleOps[T any] 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 *T) 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 *T) cty.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 *T) bool

	// HashKey provides a hashing function for values of the corresponding
	// capsule type. If defined, cty will use the resulting hashes as part
	// of the implementation of sets whose element type is or contains the
	// corresponding capsule type.
	//
	// If a capsule type defines HashValue then the function _must_ return
	// an equal hash value for any two values that would cause Equals or
	// RawEquals to return true when given those values. If a given type
	// does not uphold that assumption then sets including this type will
	// not behave correctly.
	HashKey func(v *T) string

	// 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 cty.Type) func(*T, cty.Path) (cty.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 cty.Type) func(cty.Value, cty.Path) (*T, 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 familiar 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{}

	// CustomExpressionDecoder is a function that overrides the usual
	// hcl evaluation. It takes precedence over the function that may
	// be returned from ExtensionData
	CustomExpressionDecoder func(expr hcl.Expression, evalCtx *hcl.EvalContext) (*T, diagnostics.Diag)
}

CapsuleOps represents a set of overloaded operations for a capsule type. This struct is identical to cty.CapsuleOps, except that it specifies the types of the arguments to functions. It will be converted to cty.CapsuleOps behind the scenes.

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 Codec

type Codec[T any] struct {
	Decoder[*T]
	Encoder[T]
}

Codec is both an Encoder and a Decoder for *T.

func NewCodec

func NewCodec[T any](friendlyName string, capsuleOps *CapsuleOps[T]) *Codec[T]

NewCodec creates a Codec (encoder + decoder). Will use cty.Capsule if capsuleOps is nil, and cty.CapsuleWithOps otherwise

func (*Codec) CtyType

func (e *Codec) CtyType() cty.Type

CtyType returns the cty type of the encoded values.

func (*Codec) CtyTypeEqual

func (e *Codec) CtyTypeEqual(ty cty.Type) bool

CtyTypeEqual checks if the given cty type can be decoded into T. This is the strictest check, requiring that the given cty type was produced by this Encoder.

func (*Codec) Decodable

func (d *Codec) Decodable(ty cty.Type) bool

Decodable checks if the given cty type can be decoded into T. This is a loose check, for example it allows decoding value that implements interface T.

func (*Codec) GoType

func (d *Codec) GoType() reflect.Type

GoType returns the go type of the decoded values.

func (*Codec) TypeEqual

func (d *Codec) TypeEqual(ty cty.Type) bool

TypeEqual checks if the given cty type can be decoded into T. This is a stricter check, requiring that encapsulated type is exactly T.

func (*Codec) ValCtyTypeEqual

func (e *Codec) ValCtyTypeEqual(v cty.Value) bool

ValCtyTypeEqual checks if the given cty value can be decoded into T. This is the strictest check, requiring that the given cty value was produced by this Encoder.

func (*Codec) ValDecodable

func (d *Codec) ValDecodable(v cty.Value) bool

ValDecodable checks if the given cty value can be decoded into T. This is a loose check, for example it allows decoding value that implements interface T.

func (*Codec) ValTypeEqual

func (d *Codec) ValTypeEqual(v cty.Value) bool

ValTypeEqual checks if the given cty value can be decoded into T. This is a stricter check, requiring that encapsulated type is exactly T.

type Decoder

type Decoder[T any] struct {
	// contains filtered or unexported fields
}

Decoder extracts the encapsulated value from cty.Value.

func NewDecoder

func NewDecoder[T any]() *Decoder[T]

func (*Decoder) Decodable

func (d *Decoder) Decodable(ty cty.Type) bool

Decodable checks if the given cty type can be decoded into T. This is a loose check, for example it allows decoding value that implements interface T.

func (*Decoder[T]) FromCty

func (d *Decoder[T]) FromCty(v cty.Value) (result T, err error)

FromCty decodes the encapsulated T from cty.Value. Returns an error if the value can't be decoded into T.

func (*Decoder) GoType

func (d *Decoder) GoType() reflect.Type

GoType returns the go type of the decoded values.

func (*Decoder[T]) MustFromCty

func (d *Decoder[T]) MustFromCty(v cty.Value) T

MustFromCty decodes the encapsulated T from cty.Value. Panics if the value can't be decoded into T.

func (*Decoder) TypeEqual

func (d *Decoder) TypeEqual(ty cty.Type) bool

TypeEqual checks if the given cty type can be decoded into T. This is a stricter check, requiring that encapsulated type is exactly T.

func (*Decoder) ValDecodable

func (d *Decoder) ValDecodable(v cty.Value) bool

ValDecodable checks if the given cty value can be decoded into T. This is a loose check, for example it allows decoding value that implements interface T.

func (*Decoder) ValTypeEqual

func (d *Decoder) ValTypeEqual(v cty.Value) bool

ValTypeEqual checks if the given cty value can be decoded into T. This is a stricter check, requiring that encapsulated type is exactly T.

type DecoderI

type DecoderI interface {
	Decodable(ty cty.Type) bool
	GoType() reflect.Type
	TypeEqual(ty cty.Type) bool
	ValDecodable(v cty.Value) bool
	ValTypeEqual(v cty.Value) bool
	// contains filtered or unexported methods
}

Non-generic decoder interface

type Encoder

type Encoder[T any] struct {
	// contains filtered or unexported fields
}

Encoder encapsulates *T into cty.Value.

func NewEncoder

func NewEncoder[T any](friendlyName string, capsuleOps *CapsuleOps[T]) *Encoder[T]

NewEncoder creates an Encoder. Will use cty.Capsule if capsuleOps is nil, and cty.CapsuleWithOps otherwise

func (*Encoder) CtyType

func (e *Encoder) CtyType() cty.Type

CtyType returns the cty type of the encoded values.

func (*Encoder) CtyTypeEqual

func (e *Encoder) CtyTypeEqual(ty cty.Type) bool

CtyTypeEqual checks if the given cty type can be decoded into T. This is the strictest check, requiring that the given cty type was produced by this Encoder.

func (*Encoder[T]) ToCty

func (e *Encoder[T]) ToCty(val *T) cty.Value

ToCty encapsulates *T into cty.Value.

func (*Encoder) ValCtyTypeEqual

func (e *Encoder) ValCtyTypeEqual(v cty.Value) bool

ValCtyTypeEqual checks if the given cty value can be decoded into T. This is the strictest check, requiring that the given cty value was produced by this Encoder.

func (*Encoder[T]) ValToCty

func (e *Encoder[T]) ValToCty(val T) cty.Value

ValToCty is a convenience function that encapsulates &val into cty.Value.

type EncoderI

type EncoderI interface {
	CtyType() cty.Type
	CtyTypeEqual(ty cty.Type) bool
	ValCtyTypeEqual(v cty.Value) bool
	// contains filtered or unexported methods
}

Non-generic Encoder interface

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL