github.com/coveo/gotemplate@v2.7.7+incompatible/hcl/hcl.go (about) 1 package hcl 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "reflect" 7 8 "github.com/coveo/gotemplate/collections" 9 "github.com/coveo/gotemplate/collections/implementation" 10 "github.com/coveo/gotemplate/errors" 11 "github.com/hashicorp/hcl" 12 ) 13 14 // Expose hcl public objects 15 var ( 16 Decode = hcl.Decode 17 DecodeObject = hcl.DecodeObject 18 Parse = hcl.Parse 19 ParseBytes = hcl.ParseBytes 20 ParseString = hcl.ParseString 21 ) 22 23 func (l hclList) String() string { 24 result, err := MarshalInternal(l.AsArray()) 25 if err != nil { 26 panic(err) 27 } 28 return string(result) 29 } 30 31 func (d hclDict) String() string { 32 result, err := Marshal(d.AsMap()) 33 if err != nil { 34 panic(err) 35 } 36 return string(result) 37 } 38 39 func (l hclList) PrettyPrint() string { 40 result, _ := MarshalIndent(l.AsArray(), "", " ") 41 return string(result) 42 } 43 44 func (d hclDict) PrettyPrint() string { 45 result, _ := MarshalIndent(d.AsMap(), "", " ") 46 return string(result) 47 } 48 49 var _ = func() int { 50 collections.TypeConverters["hcl"] = Unmarshal 51 return 0 52 }() 53 54 // Unmarshal adds support to single array and struct representation 55 func Unmarshal(bs []byte, out interface{}) (err error) { 56 defer func() { err = errors.Trap(err, recover()) }() 57 bs = append(bytes.TrimSpace(bs), byte('\n')) 58 59 if err = hcl.Unmarshal(bs, out); err != nil { 60 bs = append([]byte("_="), bs...) 61 var temp hclDict 62 if errInternalHcl := hcl.Unmarshal(bs, &temp); errInternalHcl != nil { 63 return err 64 } 65 err = nil 66 reflect.ValueOf(out).Elem().Set(reflect.ValueOf(temp["_"])) 67 } 68 69 transform(out) 70 return 71 } 72 73 // Load loads hcl file into variable 74 func Load(filename string) (result interface{}, err error) { 75 var content []byte 76 if content, err = ioutil.ReadFile(filename); err == nil { 77 err = Unmarshal(content, &result) 78 } 79 return 80 } 81 82 // Marshal serialize values to hcl format 83 func Marshal(value interface{}) ([]byte, error) { return MarshalIndent(value, "", "") } 84 85 // MarshalIndent serialize values to hcl format with indentation 86 func MarshalIndent(value interface{}, prefix, indent string) ([]byte, error) { 87 result, err := marshalHCL(collections.ToNativeRepresentation(value), true, true, prefix, indent) 88 return []byte(result), err 89 } 90 91 // MarshalInternal serialize values to hcl format for result used in outer hcl struct 92 func MarshalInternal(value interface{}) ([]byte, error) { 93 result, err := marshalHCL(collections.ToNativeRepresentation(value), false, false, "", "") 94 return []byte(result), err 95 } 96 97 // MarshalTFVars serialize values to hcl format (without hcl map format) 98 func MarshalTFVars(value interface{}) ([]byte, error) { return MarshalTFVarsIndent(value, "", "") } 99 100 // MarshalTFVarsIndent serialize values to hcl format with indentation (without hcl map format) 101 func MarshalTFVarsIndent(value interface{}, prefix, indent string) ([]byte, error) { 102 result, err := marshalHCL(collections.ToNativeRepresentation(value), false, true, prefix, indent) 103 return []byte(result), err 104 } 105 106 // SingleContext converts array of 1 to single object otherwise, let the context unchanged 107 func SingleContext(context ...interface{}) interface{} { 108 if len(context) == 1 { 109 return context[0] 110 } 111 return context 112 } 113 114 type ( 115 helperBase = implementation.BaseHelper 116 helperList = implementation.ListHelper 117 helperDict = implementation.DictHelper 118 ) 119 120 var needConversionImpl = implementation.NeedConversion 121 122 //go:generate genny -pkg=hcl -in=../collections/implementation/generic.go -out=generated_impl.go gen "ListTypeName=List DictTypeName=Dictionary base=hcl" 123 //go:generate genny -pkg=hcl -in=../collections/implementation/generic_test.go -out=generated_test.go gen "base=hcl"