Skip to content

Commit 6f912e5

Browse files
authored
tfprotov5+tfprotov6: Introduce ValueType() methods for Schema types (#158)
Reference: #128 Reference: #157 This methods implement standard conversion logic from `Schema*` types into their associated `tftypes.Type` equivalent. For example, these can be used to prepare calls to the `(DynamicValue).Unmarshal()` method, which is necessary in many RPCs. Preferably, these methods would have been named `Type()`, however the `SchemaAttribute` type implements a `Type` field and Go does not permit overlapping field and method names. Instead, the name `ValueType()` was chosen as an alternate designation as the `tftypes.Type` really represents a data value type, instead of a type constraint (sometimes also referred to as a schema type).
1 parent a939840 commit 6f912e5

File tree

5 files changed

+2020
-0
lines changed

5 files changed

+2020
-0
lines changed

.changelog/158.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:enhancement
2+
tfprotov5: Added `ValueType()` methods to `Schema`, `SchemaAttribute`, `SchemaBlock`, and `SchemaNestedBlock` types.
3+
```
4+
5+
```release-note:enhancement
6+
tfprotov6: Added `ValueType()` methods to `Schema`, `SchemaAttribute`, `SchemaBlock`, `SchemaNestedBlock`, and `SchemaObject` types.
7+
```

tfprotov5/schema.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ type Schema struct {
6868
Block *SchemaBlock
6969
}
7070

71+
// ValueType returns the tftypes.Type for a Schema.
72+
//
73+
// If Schema is missing, an empty Object is returned.
74+
func (s *Schema) ValueType() tftypes.Type {
75+
if s == nil {
76+
return tftypes.Object{
77+
AttributeTypes: map[string]tftypes.Type{},
78+
}
79+
}
80+
81+
return s.Block.ValueType()
82+
}
83+
7184
// SchemaBlock represents a block in a schema. Blocks are how Terraform creates
7285
// groupings of attributes. In configurations, they don't use the equals sign
7386
// and use dynamic instead of list comprehensions.
@@ -105,6 +118,51 @@ type SchemaBlock struct {
105118
Deprecated bool
106119
}
107120

121+
// ValueType returns the tftypes.Type for a SchemaBlock.
122+
//
123+
// If SchemaBlock is missing, an empty Object is returned.
124+
func (s *SchemaBlock) ValueType() tftypes.Type {
125+
if s == nil {
126+
return tftypes.Object{
127+
AttributeTypes: map[string]tftypes.Type{},
128+
}
129+
}
130+
131+
attributeTypes := map[string]tftypes.Type{}
132+
133+
for _, attribute := range s.Attributes {
134+
if attribute == nil {
135+
continue
136+
}
137+
138+
attributeType := attribute.ValueType()
139+
140+
if attributeType == nil {
141+
continue
142+
}
143+
144+
attributeTypes[attribute.Name] = attributeType
145+
}
146+
147+
for _, block := range s.BlockTypes {
148+
if block == nil {
149+
continue
150+
}
151+
152+
blockType := block.ValueType()
153+
154+
if blockType == nil {
155+
continue
156+
}
157+
158+
attributeTypes[block.TypeName] = blockType
159+
}
160+
161+
return tftypes.Object{
162+
AttributeTypes: attributeTypes,
163+
}
164+
}
165+
108166
// SchemaAttribute represents a single attribute within a schema block.
109167
// Attributes are the fields users can set in configuration using the equals
110168
// sign, can assign to variables, can interpolate, and can use list
@@ -162,6 +220,17 @@ type SchemaAttribute struct {
162220
Deprecated bool
163221
}
164222

223+
// ValueType returns the tftypes.Type for a SchemaAttribute.
224+
//
225+
// If SchemaAttribute is missing, nil is returned.
226+
func (s *SchemaAttribute) ValueType() tftypes.Type {
227+
if s == nil {
228+
return nil
229+
}
230+
231+
return s.Type
232+
}
233+
165234
// SchemaNestedBlock is a nested block within another block. See SchemaBlock
166235
// for more information on blocks.
167236
type SchemaNestedBlock struct {
@@ -198,6 +267,39 @@ type SchemaNestedBlock struct {
198267
MaxItems int64
199268
}
200269

270+
// ValueType returns the tftypes.Type for a SchemaNestedBlock.
271+
//
272+
// If SchemaNestedBlock is missing or the Nesting mode is invalid, nil is
273+
// returned.
274+
func (s *SchemaNestedBlock) ValueType() tftypes.Type {
275+
if s == nil {
276+
return nil
277+
}
278+
279+
blockType := s.Block.ValueType()
280+
281+
switch s.Nesting {
282+
case SchemaNestedBlockNestingModeGroup:
283+
return blockType
284+
case SchemaNestedBlockNestingModeList:
285+
return tftypes.List{
286+
ElementType: blockType,
287+
}
288+
case SchemaNestedBlockNestingModeMap:
289+
return tftypes.Map{
290+
ElementType: blockType,
291+
}
292+
case SchemaNestedBlockNestingModeSet:
293+
return tftypes.Set{
294+
ElementType: blockType,
295+
}
296+
case SchemaNestedBlockNestingModeSingle:
297+
return blockType
298+
default:
299+
return nil
300+
}
301+
}
302+
201303
// SchemaNestedBlockNestingMode indicates the nesting mode for
202304
// SchemaNestedBlocks. The nesting mode determines the number of instances of
203305
// the block allowed, how many labels the block expects, and the data structure

0 commit comments

Comments
 (0)