99 "github.com/hashicorp/terraform-plugin-framework/types"
1010)
1111
12- type TFTypeValueType uint8
13-
1412// ValueToBoolType ensures we have a types.Bool literal
1513func ValueToBoolType (v attr.Value ) types.Bool {
1614 if vb , ok := v .(types.Bool ); ok {
@@ -128,70 +126,69 @@ func ValueToStringType(v attr.Value) types.String {
128126//
129127// A 'nil' response from this function means the attribute's value was defined to a non-"empty" value at runtime. See
130128// function body for a particular type if you're interested in what "empty" means.
131- func TestAttributeValueState (v attr.Value ) error {
129+ func TestAttributeValueState (av attr.Value ) error {
132130 var (
133131 undefined bool
134132 null bool
135133 empty bool
136134 )
137135
138- // first, check for unknown and null
139- switch v .( type ) {
136+ switch av .( type ) {
137+ // bool values cannot be "empty"
140138 case types.Bool , * types.Bool :
141- tv := ValueToBoolType (v )
139+ tv := ValueToBoolType (av )
142140 undefined = tv .Unknown
143141 null = tv .Null
144- // bool values cannot be "empty"
145142
143+ // float values cannot be "empty"
146144 case types.Float64 , * types.Float64 :
147- tv := ValueToFloat64Type (v )
145+ tv := ValueToFloat64Type (av )
148146 undefined = tv .Unknown
149147 null = tv .Null
150- // float values cannot be "empty"
151148
149+ // int values cannot be "empty"
152150 case types.Int64 , * types.Int64 :
153- tv := ValueToInt64Type (v )
151+ tv := ValueToInt64Type (av )
154152 undefined = tv .Unknown
155153 null = tv .Null
156- // int values cannot be "empty"
157154
158155 case types.List , * types.List :
159- tv := ValueToListType (v )
156+ tv := ValueToListType (av )
160157 undefined = tv .Unknown
161158 null = tv .Null
162- empty = AttributeValueLength (v ) == 0
159+ empty = AttributeValueLength (av ) == 0
163160
164161 case types.Map , * types.Map :
165- tv := ValueToMapType (v )
162+ tv := ValueToMapType (av )
166163 undefined = tv .Unknown
167164 null = tv .Null
168- empty = AttributeValueLength (v ) == 0
165+ empty = AttributeValueLength (av ) == 0
169166
170167 case types.Number , * types.Number :
171- tv := ValueToNumberType (v )
168+ tv := ValueToNumberType (av )
172169 undefined = tv .Unknown
173170 null = tv .Null
174171
172+ // todo: implement object "emptiness" check
175173 case types.Object , * types.Object :
176- tv := ValueToObjectType (v )
174+ tv := ValueToObjectType (av )
177175 undefined = tv .Unknown
178176 null = tv .Null
179- // todo: implement object "emptiness" check
180177
181178 case types.Set , * types.Set :
182- tv := ValueToSetType (v )
179+ tv := ValueToSetType (av )
183180 undefined = tv .Unknown
184181 null = tv .Null
185- empty = AttributeValueLength (v ) > 0
182+ empty = AttributeValueLength (av ) > 0
186183
187184 case types.String , * types.String :
188- tv := ValueToStringType (v )
185+ tv := ValueToStringType (av )
189186 undefined = tv .Unknown
190187 null = tv .Null
191- empty = StringValueToString (v ) == ""
188+ empty = StringValueToString (av ) == ""
192189
193190 default :
194- panic ( fmt . Sprintf ( "no way to test for valued state for types %T " , v ) )
191+ return ValueTypeUnhandledError ( "length_check " , av )
195192 }
196193
197194 if undefined {
@@ -257,7 +254,22 @@ func AttributeValueToString(v attr.Value) string {
257254 return StringValueToString (v )
258255
259256 default :
260- panic (fmt .Sprintf ("no stringer func registered for type %T" , v ))
257+ return fmt .Sprintf ("%T" , v )
258+ }
259+ }
260+
261+ // AttributeValueToStrings attempts to convert the provided attr.Value into a slice of strings.
262+ func AttributeValueToStrings (av attr.Value ) []string {
263+ switch av .(type ) {
264+ case types.List , * types.List :
265+ return StringListToStrings (av )
266+
267+ case types.Set , * types.Set :
268+ return StringSetToStrings (av )
269+ default :
270+ out := make ([]string , 0 )
271+ out = append (out , ValueToStringType (av ).Value )
272+ return out
261273 }
262274}
263275
@@ -341,6 +353,13 @@ func NumberValueToInt64(v attr.Value) (int64, big.Accuracy) {
341353 return vt .Value .Int64 ()
342354}
343355
356+ // NumberValueToInt accepts either a types.Number or *types.Number, returning an int representation of the *big.Float
357+ // value within. It will return [0, big.Exact] if the value was not set
358+ func NumberValueToInt (v attr.Value ) (int , big.Accuracy ) {
359+ iv , acc := NumberValueToInt64 (v )
360+ return int (iv ), acc
361+ }
362+
344363// NumberValueToFloat64 accepts either a types.Number or *types.Number, returning a float64 representation of the
345364// *big.Float value within. It will return [0.0, big.Exact] of the value was not set.
346365func NumberValueToFloat64 (v attr.Value ) (float64 , big.Accuracy ) {
@@ -410,13 +429,35 @@ func StringValueToStringPtr(v attr.Value) *string {
410429 return vPtr
411430}
412431
432+ // StringListToStrings accepts an instance of either types.List or *types.List where ElemType MUST be types.StringType,
433+ // returning a slice of strings of the value of each element
434+ func StringListToStrings (v attr.Value ) []string {
435+ vt := ValueToListType (v )
436+ out := make ([]string , len (vt .Elems ))
437+ for i , ve := range vt .Elems {
438+ out [i ] = StringValueToString (ve )
439+ }
440+ return out
441+ }
442+
443+ // StringSetToStrings accepts an instance of either types.Set or *types.Set where ElemType MUST be types.StringType,
444+ // returning a slice of strings of the value of each element
445+ func StringSetToStrings (v attr.Value ) []string {
446+ vt := ValueToSetType (v )
447+ out := make ([]string , len (vt .Elems ))
448+ for i , ve := range vt .Elems {
449+ out [i ] = StringValueToString (ve )
450+ }
451+ return out
452+ }
453+
413454// Int64ListToInts accepts an instance of either types.List or *types.List where ElemType MUST be types.Int64Type,
414455// returning a slice of ints of the value of each element.
415456func Int64ListToInts (v attr.Value ) []int {
416457 vt := ValueToListType (v )
417458 out := make ([]int , len (vt .Elems ))
418459 for i , ve := range vt .Elems {
419- out [i ] = Int64ValueToInt (ve .(types. Int64 ) )
460+ out [i ] = Int64ValueToInt (ve )
420461 }
421462 return out
422463}
@@ -427,7 +468,31 @@ func Int64SetToInts(v attr.Value) []int {
427468 vt := ValueToSetType (v )
428469 out := make ([]int , len (vt .Elems ))
429470 for i , ve := range vt .Elems {
430- out [i ] = Int64ValueToInt (ve .(types.Int64 ))
471+ out [i ] = Int64ValueToInt (ve )
472+ }
473+ return out
474+ }
475+
476+ // NumberListToInts accepts either an instance of types.List or *types.List where ElemType MUST be types.NumberType
477+ // returning a slice of ints of the value of each element
478+ func NumberListToInts (v attr.Value ) []int {
479+ vt := ValueToListType (v )
480+ out := make ([]int , len (vt .Elems ))
481+ for i , ve := range vt .Elems {
482+ iv , _ := NumberValueToInt (ve )
483+ out [i ] = iv
484+ }
485+ return out
486+ }
487+
488+ // NumberSetToInts accepts either an instance of types.Set or *types.Set where ElemType MUST be types.NumberType
489+ // returning a slice of ints of the value of each element
490+ func NumberSetToInts (v attr.Value ) []int {
491+ vt := ValueToSetType (v )
492+ out := make ([]int , len (vt .Elems ))
493+ for i , ve := range vt .Elems {
494+ iv , _ := NumberValueToInt (ve )
495+ out [i ] = iv
431496 }
432497 return out
433498}
@@ -451,7 +516,7 @@ func AttributeValueToFloat64(v attr.Value) (float64, big.Accuracy, error) {
451516 return f , big .Exact , err
452517
453518 default :
454- panic ( fmt . Sprintf ( "unable to determine float64 value of type %T" , v ) )
519+ return 0 , 0 , ValueTypeUnhandledError ( "attr_to_float64" , v )
455520 }
456521}
457522
@@ -480,7 +545,7 @@ func AttributeValueToInt64(v attr.Value) (int64, big.Accuracy, error) {
480545 return int64 (i ), big .Exact , err
481546
482547 default :
483- panic ( fmt . Sprintf ( "unable to determine int64 value of type %T" , v ) )
548+ return 0 , 0 , ValueTypeUnhandledError ( "attr_to_int64" , v )
484549 }
485550}
486551
@@ -502,7 +567,7 @@ func AttributeValueToBigFloat(v attr.Value) (*big.Float, error) {
502567 return bf , err
503568
504569 default :
505- panic ( fmt . Sprintf ( "unable to parse type %T into *big.Float" , v ) )
570+ return nil , ValueTypeUnhandledError ( "attr_to_bigfloat" , v )
506571 }
507572}
508573
0 commit comments