|
| 1 | +package tfjson |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "errors" |
| 6 | + "fmt" |
| 7 | + |
| 8 | + "github.com/hashicorp/go-version" |
| 9 | + "github.com/zclconf/go-cty/cty" |
| 10 | +) |
| 11 | + |
| 12 | +// MetadataFunctionsFormatVersionConstraints defines the versions of the JSON |
| 13 | +// metadata functions format that are supported by this package. |
| 14 | +var MetadataFunctionsFormatVersionConstraints = "~> 1.0" |
| 15 | + |
| 16 | +// MetadataFunctions is the top-level object returned when exporting function |
| 17 | +// signatures |
| 18 | +type MetadataFunctions struct { |
| 19 | + // The version of the format. This should always match the |
| 20 | + // MetadataFunctionsFormatVersionConstraints in this package, else |
| 21 | + // unmarshaling will fail. |
| 22 | + FormatVersion string `json:"format_version"` |
| 23 | + |
| 24 | + // The signatures of the functions available in a Terraform version. |
| 25 | + Signatures map[string]*FunctionSignature `json:"function_signatures,omitempty"` |
| 26 | +} |
| 27 | + |
| 28 | +// Validate checks to ensure that MetadataFunctions is present, and the |
| 29 | +// version matches the version supported by this library. |
| 30 | +func (f *MetadataFunctions) Validate() error { |
| 31 | + if f == nil { |
| 32 | + return errors.New("metadata functions data is nil") |
| 33 | + } |
| 34 | + |
| 35 | + if f.FormatVersion == "" { |
| 36 | + return errors.New("unexpected metadata functions data, format version is missing") |
| 37 | + } |
| 38 | + |
| 39 | + constraint, err := version.NewConstraint(MetadataFunctionsFormatVersionConstraints) |
| 40 | + if err != nil { |
| 41 | + return fmt.Errorf("invalid version constraint: %w", err) |
| 42 | + } |
| 43 | + |
| 44 | + version, err := version.NewVersion(f.FormatVersion) |
| 45 | + if err != nil { |
| 46 | + return fmt.Errorf("invalid format version %q: %w", f.FormatVersion, err) |
| 47 | + } |
| 48 | + |
| 49 | + if !constraint.Check(version) { |
| 50 | + return fmt.Errorf("unsupported metadata functions format version: %q does not satisfy %q", |
| 51 | + version, constraint) |
| 52 | + } |
| 53 | + |
| 54 | + return nil |
| 55 | +} |
| 56 | + |
| 57 | +func (f *MetadataFunctions) UnmarshalJSON(b []byte) error { |
| 58 | + type rawFunctions MetadataFunctions |
| 59 | + var functions rawFunctions |
| 60 | + |
| 61 | + err := json.Unmarshal(b, &functions) |
| 62 | + if err != nil { |
| 63 | + return err |
| 64 | + } |
| 65 | + |
| 66 | + *f = *(*MetadataFunctions)(&functions) |
| 67 | + |
| 68 | + return f.Validate() |
| 69 | +} |
| 70 | + |
| 71 | +// FunctionSignature represents a function signature. |
| 72 | +type FunctionSignature struct { |
| 73 | + // Description is an optional human-readable description |
| 74 | + // of the function |
| 75 | + Description string `json:"description,omitempty"` |
| 76 | + |
| 77 | + // ReturnType is the ctyjson representation of the function's |
| 78 | + // return types based on supplying all parameters using |
| 79 | + // dynamic types. Functions can have dynamic return types. |
| 80 | + ReturnType cty.Type `json:"return_type"` |
| 81 | + |
| 82 | + // Parameters describes the function's fixed positional parameters. |
| 83 | + Parameters []*FunctionParameter `json:"parameters,omitempty"` |
| 84 | + |
| 85 | + // VariadicParameter describes the function's variadic |
| 86 | + // parameter if it is supported. |
| 87 | + VariadicParameter *FunctionParameter `json:"variadic_parameter,omitempty"` |
| 88 | +} |
| 89 | + |
| 90 | +// FunctionParameter represents a parameter to a function. |
| 91 | +type FunctionParameter struct { |
| 92 | + // Name is an optional name for the argument. |
| 93 | + Name string `json:"name,omitempty"` |
| 94 | + |
| 95 | + // Description is an optional human-readable description |
| 96 | + // of the argument |
| 97 | + Description string `json:"description,omitempty"` |
| 98 | + |
| 99 | + // IsNullable is true if null is acceptable value for the argument |
| 100 | + IsNullable bool `json:"is_nullable,omitempty"` |
| 101 | + |
| 102 | + // A type that any argument for this parameter must conform to. |
| 103 | + Type cty.Type `json:"type"` |
| 104 | +} |
0 commit comments