@@ -3,74 +3,114 @@ package acctest
33import (
44 "fmt"
55 "strings"
6+ "sync"
7+
8+ "github.com/dcarbone/terraform-plugin-framework-utils/internal/util"
69)
710
811type ConfigLiteral string
912
13+ type ConfigValueFunc func (interface {}) string
14+
15+ var (
16+ configValueFuncsMu sync.RWMutex
17+ configValueFuncs map [string ]ConfigValueFunc
18+ )
19+
20+ func SetConfigValueFunc (t interface {}, fn ConfigValueFunc ) {
21+ configValueFuncsMu .Lock ()
22+ defer configValueFuncsMu .Unlock ()
23+ configValueFuncs [util .KeyFN (t )] = fn
24+ }
25+
26+ func GetConfigValueFunc (t interface {}) (ConfigValueFunc , bool ) {
27+ configValueFuncsMu .RLock ()
28+ defer configValueFuncsMu .RUnlock ()
29+ fn , ok := configValueFuncs [util .KeyFN (t )]
30+ return fn , ok
31+ }
32+
33+ func DefaultConfigValueFuncs () map [string ]ConfigValueFunc {
34+ return map [string ]ConfigValueFunc {
35+ // nil
36+ util .KeyFN (nil ): func (_ interface {}) string { return "null" },
37+
38+ // values to print literally
39+ util .KeyFN (ConfigLiteral ("" )): func (v interface {}) string { return string (v .(ConfigLiteral )) },
40+
41+ // simple conversions
42+ util .KeyFN (false ): func (v interface {}) string { return fmt .Sprintf ("%t" , v .(bool )) },
43+ util .KeyFN (0 ): func (v interface {}) string { return fmt .Sprintf ("%d" , v .(int )) },
44+ util .KeyFN (float64 (0 )): func (v interface {}) string { return fmt .Sprintf ("%f" , v .(float64 )) },
45+
46+ // handle single and multi-line strings
47+ util .KeyFN ("" ): func (v interface {}) string {
48+ if strings .Contains (v .(string ), "\n " ) {
49+ return fmt .Sprintf ("<<EOD\n %s\n EOD" , v .(string ))
50+ } else {
51+ return fmt .Sprintf ("%q" , v .(string ))
52+ }
53+ },
54+
55+ // slices
56+
57+ util .KeyFN (make ([]interface {}, 0 )): func (v interface {}) string {
58+ formatted := make ([]string , 0 )
59+ for _ , v := range v .([]interface {}) {
60+ formatted = append (formatted , ConfigValue (v ))
61+ }
62+ return fmt .Sprintf ("[\n %s\n ]" , strings .Join (formatted , ",\n " ))
63+ },
64+ util .KeyFN (make ([]string , 0 )): func (v interface {}) string {
65+ formatted := make ([]string , 0 )
66+ for _ , v := range v .([]string ) {
67+ formatted = append (formatted , ConfigValue (v ))
68+ }
69+ return fmt .Sprintf ("[\n %s\n ]" , strings .Join (formatted , ",\n " ))
70+ },
71+ util .KeyFN (make ([]int , 0 )): func (v interface {}) string {
72+ formatted := make ([]string , 0 )
73+ for _ , v := range v .([]int ) {
74+ formatted = append (formatted , ConfigValue (v ))
75+ }
76+ return fmt .Sprintf ("[\n %s\n ]" , strings .Join (formatted , ",\n " ))
77+ },
78+ util .KeyFN (make ([]float64 , 0 )): func (v interface {}) string {
79+ formatted := make ([]string , 0 )
80+ for _ , v := range v .([]float64 ) {
81+ formatted = append (formatted , ConfigValue (v ))
82+ }
83+ return fmt .Sprintf ("[\n %s\n ]" , strings .Join (formatted , ",\n " ))
84+ },
85+
86+ // maps
87+
88+ util .KeyFN (make (map [string ]interface {})): func (v interface {}) string {
89+ inner := "{"
90+ for k , v := range v .(map [string ]interface {}) {
91+ inner = fmt .Sprintf ("%s\n %s = %s" , inner , k , ConfigValue (v ))
92+ }
93+ return fmt .Sprintf ("%s\n }" , inner )
94+ },
95+ util .KeyFN (make (map [string ]string )): func (v interface {}) string {
96+ inner := "{"
97+ for k , v := range v .(map [string ]string ) {
98+ inner = fmt .Sprintf ("%s\n %s = %s" , inner , k , ConfigValue (v ))
99+ }
100+ return fmt .Sprintf ("%s\n }" , inner )
101+ },
102+ }
103+ }
104+
105+ func init () {
106+ configValueFuncs = DefaultConfigValueFuncs ()
107+ }
108+
10109// ConfigValue attempts to convert the provided input to a Terraform config safe representation of its value
11110func ConfigValue (in interface {}) string {
12- switch in .(type ) {
13- case nil :
14- return "null"
15-
16- case ConfigLiteral :
17- return string (in .(ConfigLiteral ))
18-
19- case string :
20- if strings .Contains (in .(string ), "\n " ) {
21- return fmt .Sprintf ("<<EOD\n %s\n EOD" , in .(string ))
22- } else {
23- return fmt .Sprintf ("%q" , in .(string ))
24- }
25-
26- case bool :
27- return fmt .Sprintf ("%t" , in .(bool ))
28-
29- case int :
30- return fmt .Sprintf ("%d" , in .(int ))
31-
32- case float64 :
33- return fmt .Sprintf ("%f" , in .(float64 ))
34-
35- case []interface {}:
36- formatted := make ([]string , 0 )
37- for _ , v := range in .([]interface {}) {
38- formatted = append (formatted , ConfigValue (v ))
39- }
40- return fmt .Sprintf ("[\n %s]" , strings .Join (formatted , ",\n " ))
41- case []string :
42- formatted := make ([]string , 0 )
43- for _ , v := range in .([]string ) {
44- formatted = append (formatted , ConfigValue (v ))
45- }
46- return fmt .Sprintf ("[\n %s]" , strings .Join (formatted , ",\n " ))
47- case []int :
48- formatted := make ([]string , 0 )
49- for _ , v := range in .([]int ) {
50- formatted = append (formatted , ConfigValue (v ))
51- }
52- return fmt .Sprintf ("[\n %s]" , strings .Join (formatted , ",\n " ))
53- case []float64 :
54- formatted := make ([]string , 0 )
55- for _ , v := range in .([]float64 ) {
56- formatted = append (formatted , ConfigValue (v ))
57- }
58- return fmt .Sprintf ("[\n %s]" , strings .Join (formatted , ",\n " ))
59-
60- case map [string ]interface {}:
61- inner := "{"
62- for k , v := range in .(map [string ]interface {}) {
63- inner = fmt .Sprintf ("%s\n %s = %s" , inner , k , ConfigValue (v ))
64- }
65- return fmt .Sprintf ("%s\n }" , inner )
66- case map [string ]string :
67- inner := "{"
68- for k , v := range in .(map [string ]string ) {
69- inner = fmt .Sprintf ("%s\n %s = %s" , inner , k , ConfigValue (v ))
70- }
71- return fmt .Sprintf ("%s\n }" , inner )
72-
73- default :
111+ if fn , ok := GetConfigValueFunc (in ); ok {
112+ return fn (in )
113+ } else {
74114 panic (fmt .Sprintf ("Unable to handle config values of type %T" , in ))
75115 }
76116}
0 commit comments