|
| 1 | +package provider |
| 2 | + |
| 3 | +import ( |
| 4 | +"slices" |
| 5 | + |
| 6 | +"golang.org/x/xerrors" |
| 7 | +) |
| 8 | + |
| 9 | +// OptionType is a type of option that can be used in the 'type' argument of |
| 10 | +// a parameter. These should match types as defined in terraform: |
| 11 | +// |
| 12 | +//https://developer.hashicorp.com/terraform/language/expressions/types |
| 13 | +// |
| 14 | +// The value have to be string literals, as type constraint keywords are not |
| 15 | +// supported in providers. |
| 16 | +typeOptionTypestring |
| 17 | + |
| 18 | +const ( |
| 19 | +OptionTypeStringOptionType="string" |
| 20 | +OptionTypeNumberOptionType="number" |
| 21 | +OptionTypeBooleanOptionType="bool" |
| 22 | +OptionTypeListStringOptionType="list(string)" |
| 23 | +) |
| 24 | + |
| 25 | +funcOptionTypes() []OptionType { |
| 26 | +return []OptionType{ |
| 27 | +OptionTypeString, |
| 28 | +OptionTypeNumber, |
| 29 | +OptionTypeBoolean, |
| 30 | +OptionTypeListString, |
| 31 | +} |
| 32 | +} |
| 33 | + |
| 34 | +// ParameterFormType is the list of supported form types for display in |
| 35 | +// the Coder "create workspace" form. These form types are functional as well |
| 36 | +// as cosmetic. Refer to `formTypeTruthTable` for the allowed pairings. |
| 37 | +// For example, "multi-select" has the type "list(string)" but the option |
| 38 | +// values are "string". |
| 39 | +typeParameterFormTypestring |
| 40 | + |
| 41 | +const ( |
| 42 | +ParameterFormTypeDefaultParameterFormType="" |
| 43 | +ParameterFormTypeRadioParameterFormType="radio" |
| 44 | +ParameterFormTypeSliderParameterFormType="slider" |
| 45 | +ParameterFormTypeInputParameterFormType="input" |
| 46 | +ParameterFormTypeDropdownParameterFormType="dropdown" |
| 47 | +ParameterFormTypeCheckboxParameterFormType="checkbox" |
| 48 | +ParameterFormTypeSwitchParameterFormType="switch" |
| 49 | +ParameterFormTypeMultiSelectParameterFormType="multi-select" |
| 50 | +ParameterFormTypeTagSelectParameterFormType="tag-select" |
| 51 | +ParameterFormTypeTextAreaParameterFormType="textarea" |
| 52 | +ParameterFormTypeErrorParameterFormType="error" |
| 53 | +) |
| 54 | + |
| 55 | +// ParameterFormTypes should be kept in sync with the enum list above. |
| 56 | +funcParameterFormTypes() []ParameterFormType { |
| 57 | +return []ParameterFormType{ |
| 58 | +// Intentionally omit "ParameterFormTypeDefault" from this set. |
| 59 | +// It is a valid enum, but will always be mapped to a real value when |
| 60 | +// being used. |
| 61 | +ParameterFormTypeRadio, |
| 62 | +ParameterFormTypeSlider, |
| 63 | +ParameterFormTypeInput, |
| 64 | +ParameterFormTypeDropdown, |
| 65 | +ParameterFormTypeCheckbox, |
| 66 | +ParameterFormTypeSwitch, |
| 67 | +ParameterFormTypeMultiSelect, |
| 68 | +ParameterFormTypeTagSelect, |
| 69 | +ParameterFormTypeTextArea, |
| 70 | +ParameterFormTypeError, |
| 71 | +} |
| 72 | +} |
| 73 | + |
| 74 | +// formTypeTruthTable is a map of [`type`][`optionCount` > 0] to `form_type`. |
| 75 | +// The first value in the slice is the default value assuming `form_type` is |
| 76 | +// not specified. |
| 77 | +// |
| 78 | +// The boolean key indicates whether the `options` field is specified. |
| 79 | +// | Type | Options | Specified Form Type | form_type | Notes | |
| 80 | +// |-------------------|---------|---------------------|----------------|--------------------------------| |
| 81 | +// | `string` `number` | Y | | `radio` | | |
| 82 | +// | `string` `number` | Y | `dropdown` | `dropdown` | | |
| 83 | +// | `string` `number` | N | | `input` | | |
| 84 | +// | `string` | N | 'textarea' | `textarea` | | |
| 85 | +// | `number` | N | 'slider' | `slider` | min/max validation | |
| 86 | +// | `bool` | Y | | `radio` | | |
| 87 | +// | `bool` | N | | `checkbox` | | |
| 88 | +// | `bool` | N | `switch` | `switch` | | |
| 89 | +// | `list(string)` | Y | | `radio` | | |
| 90 | +// | `list(string)` | N | | `tag-select` | | |
| 91 | +// | `list(string)` | Y | `multi-select` | `multi-select` | Option values will be `string` | |
| 92 | +varformTypeTruthTable=map[OptionType]map[bool][]ParameterFormType{ |
| 93 | +OptionTypeString: { |
| 94 | +true: {ParameterFormTypeRadio,ParameterFormTypeDropdown}, |
| 95 | +false: {ParameterFormTypeInput,ParameterFormTypeTextArea}, |
| 96 | +}, |
| 97 | +OptionTypeNumber: { |
| 98 | +true: {ParameterFormTypeRadio,ParameterFormTypeDropdown}, |
| 99 | +false: {ParameterFormTypeInput,ParameterFormTypeSlider}, |
| 100 | +}, |
| 101 | +OptionTypeBoolean: { |
| 102 | +true: {ParameterFormTypeRadio}, |
| 103 | +false: {ParameterFormTypeCheckbox,ParameterFormTypeSwitch}, |
| 104 | +}, |
| 105 | +OptionTypeListString: { |
| 106 | +true: {ParameterFormTypeRadio,ParameterFormTypeMultiSelect}, |
| 107 | +false: {ParameterFormTypeTagSelect}, |
| 108 | +}, |
| 109 | +} |
| 110 | + |
| 111 | +// ValidateFormType handles the truth table for the valid set of `type` and |
| 112 | +// `form_type` options. |
| 113 | +// The OptionType is also returned because it is possible the 'type' of the |
| 114 | +// 'value' & 'default' fields is different from the 'type' of the options. |
| 115 | +// The use case is when using multi-select. The options are 'string' and the |
| 116 | +// value is 'list(string)'. |
| 117 | +funcValidateFormType(paramTypeOptionType,optionCountint,specifiedFormTypeParameterFormType) (OptionType,ParameterFormType,error) { |
| 118 | +allowed,ok:=formTypeTruthTable[paramType][optionCount>0] |
| 119 | +if!ok||len(allowed)==0 { |
| 120 | +returnparamType,specifiedFormType,xerrors.Errorf("value type %q is not supported for 'form_types'",paramType) |
| 121 | +} |
| 122 | + |
| 123 | +ifspecifiedFormType==ParameterFormTypeDefault { |
| 124 | +// handle the default case |
| 125 | +specifiedFormType=allowed[0] |
| 126 | +} |
| 127 | + |
| 128 | +if!slices.Contains(allowed,specifiedFormType) { |
| 129 | +returnparamType,specifiedFormType,xerrors.Errorf("value type %q is not supported for 'form_types'",specifiedFormType) |
| 130 | +} |
| 131 | + |
| 132 | +// This is the only current special case. If 'multi-select' is selected, the type |
| 133 | +// of 'value' and an options 'value' are different. The type of the parameter is |
| 134 | +// `list(string)` but the type of the individual options is `string`. |
| 135 | +ifparamType==OptionTypeListString&&specifiedFormType==ParameterFormTypeMultiSelect { |
| 136 | +returnOptionTypeString,ParameterFormTypeMultiSelect,nil |
| 137 | +} |
| 138 | + |
| 139 | +returnparamType,specifiedFormType,nil |
| 140 | +} |
| 141 | + |
| 142 | +functoStrings[A~string](l []A) []string { |
| 143 | +varr []string |
| 144 | +for_,v:=rangel { |
| 145 | +r=append(r,string(v)) |
| 146 | +} |
| 147 | +returnr |
| 148 | +} |