Skip to content

Commit

Permalink
Merge pull request #1 from matthewhartstonge/feature/generify-type-an…
Browse files Browse the repository at this point in the history
…d-value

feature/generify-type-and-value
  • Loading branch information
matthewhartstonge committed Oct 5, 2022
2 parents a4888ef + b6049a8 commit 72743a5
Show file tree
Hide file tree
Showing 6 changed files with 669 additions and 117 deletions.
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ and DCE 1.1: Authentication and Security Services.

### Schema

Replace usages of `types.StringType` with `uuidtype.Type{}`.
Replace usages of `types.StringType` with `uuidtype.UUIDType{}`.

Given the previous schema attribute:

Expand All @@ -27,14 +27,14 @@ The updated schema will look like:
```go
tfsdk.Attribute{
Required: true
Type: uuidtype.Type{}
Type: uuidtype.UUIDType{}
}
```

### Schema Data Model

Replace usage of `string`, `*string`, or `types.String` in schema data models
with `uuidtype.Value`.
with `uuidtype.UUID`.

Given the previous schema data model:

Expand All @@ -50,7 +50,7 @@ The updated schema data model will look like:
```go
type ThingResourceModel struct {
// ...
Example uuidtype.Value `tfsdk:"example"`
Example uuidtype.UUID `tfsdk:"example"`
}
```

Expand All @@ -62,24 +62,24 @@ a known `uuid` value.

### Writing Values

Create a `uuidtype.Value` by calling one of these functions:
Create a `uuidtype.UUID` by calling one of these functions:

- `NullValue() Value`: creates a `null` value.
- `UnknownValue() Value`: creates an unknown value.
- `StringValue(string, path.Path) (Value, diag.Diagnostics)`: creates a known
- `NullUUID() UUID`: creates a `null` value.
- `UnknownUUID() UUID`: creates an unknown value.
- `UUIDFromString(string, path.Path) (UUID, diag.Diagnostics)`: creates a known
value using the given `string` or returns validation errors if `string` is
not in the expected UUID format.
- `MustValue(string) Value` creates a known value using the given string, but
will panic if it's unparseable as a UUID.
- `UUIDFromGoogleUUID(uuid.UUID) UUID` creates a known value given a
Google [uuid.UUID](https://pkg.go.dev/github.com/google/uuid#UUID) struct.

### Adding the Dependency

All functionality is located in the `github.com/matthewhartstonge/terraform-plugin-framework-type-uuid/uuidtype`
All functionality is located in the `github.com/matthewhartstonge/terraform-plugin-framework-type-uuid/uuidtypes`
package. Add this as an `import` as required to your relevant Go files.

Run the following Go commands to fetch the latest version and ensure all module files are up-to-date.

```shell
go get github.com/matthewhartstonge/terraform-plugin-framework-type-uuidtype@latest
go get github.com/matthewhartstonge/terraform-plugin-framework-type-uuid@latest
go mod tidy
```
4 changes: 2 additions & 2 deletions uuidtype/doc.go → uuidtypes/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

// Package uuidtype implements a terraform-plugin-framework attr.Type and
// Package uuidtypes implements a terraform-plugin-framework attr.Type and
// attr.Value for Universally Unique IDentifiers (UUIDs) as defined in
// [RFC 4122].
//
// [RFC 4122]: https://tools.ietf.org/html/rfc4122
package uuidtype
package uuidtypes
89 changes: 43 additions & 46 deletions uuidtype/value.go → uuidtypes/uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package uuidtype
package uuidtypes

import (
// Standard Library Imports
Expand All @@ -30,25 +30,25 @@ import (

// Ensure Implementation matches the expected interfaces.
var (
_ attr.Value = Value{}
_ attr.Value = UUID{}
)

// NullValue returns a null UUID value.
func NullValue() Value {
return Value{null: true}
// UUIDNull returns a null UUID value.
func UUIDNull() UUID {
return UUID{null: true}
}

// UnknownValue returns an unknown UUID value.
func UnknownValue() Value {
return Value{unknown: true}
// UUIDUnknown returns an unknown UUID value.
func UUIDUnknown() UUID {
return UUID{unknown: true}
}

// StringValue returns a value or any errors when attempting to parse the string
// as a UUID.
func StringValue(value string, schemaPath path.Path) (Value, diag.Diagnostics) {
// UUIDFromString returns a value or any errors when attempting to parse the
// string as a UUID.
func UUIDFromString(value string, schemaPath path.Path) (UUID, diag.Diagnostics) {
validUUID, err := uuid.Parse(value)
if err != nil {
return UnknownValue(), diag.Diagnostics{
return UUIDUnknown(), diag.Diagnostics{
diag.NewAttributeErrorDiagnostic(
schemaPath,
"Invalid UUID String Value",
Expand All @@ -60,89 +60,86 @@ func StringValue(value string, schemaPath path.Path) (Value, diag.Diagnostics) {
}
}

return Value{
value: validUUID.String(),
return UUID{
value: validUUID,
}, nil
}

// MustValue expects a valid UUID, otherwise will panic on error.
func MustValue(value string) Value {
validUUID, err := uuid.Parse(value)
if err != nil {
panic(err)
}

return Value{
value: validUUID.String(),
// UUIDFromGoogleUUID expects a valid google/uuid.UUID and returns a Terraform
// UUID Value.
func UUIDFromGoogleUUID(value uuid.UUID) UUID {
return UUID{
value: value,
}
}

// Value provides a concrete implementation of a UUID tftypes.Value for the
// UUID provides a concrete implementation of a UUID tftypes.Value for the
// Terraform Plugin framework.
type Value struct {
type UUID struct {
null bool
unknown bool
value string
value uuid.UUID
}

// Type returns the UUID type that created the Value.
func (v Value) Type(_ context.Context) attr.Type {
return Type{}
// Type returns the UUID type that created the UUID.
func (u UUID) Type(_ context.Context) attr.Type {
return UUIDType{}
}

// ToTerraformValue returns the UUID as a tftypes.Value.
func (v Value) ToTerraformValue(_ context.Context) (tftypes.Value, error) {
if v.IsNull() {
func (u UUID) ToTerraformValue(_ context.Context) (tftypes.Value, error) {
if u.IsNull() {
return tftypes.NewValue(tftypes.String, nil), nil
}

if v.IsUnknown() {
if u.IsUnknown() {
return tftypes.NewValue(tftypes.String, tftypes.UnknownValue), nil
}

return tftypes.NewValue(tftypes.String, v.value), nil
return tftypes.NewValue(tftypes.String, u.value.String()), nil
}

// IsNull returns true if the uuid represents a null value.
func (v Value) IsNull() bool {
return v.null
func (u UUID) IsNull() bool {
return u.null
}

// IsUnknown returns true if the uuid represents an unknown value.
func (v Value) IsUnknown() bool {
return v.unknown
func (u UUID) IsUnknown() bool {
return u.unknown
}

// Equal returns true if the uuid is semantically equal to the Value passed as
// an argument.
func (v Value) Equal(other attr.Value) bool {
otherValue, ok := other.(Value)
func (u UUID) Equal(other attr.Value) bool {
otherValue, ok := other.(UUID)
if !ok {
return false
}

if otherValue.null != v.null {
if otherValue.null != u.null {
return false
}

if otherValue.unknown != v.unknown {
if otherValue.unknown != u.unknown {
return false
}

return otherValue.value == v.value
// perform a byte-for-byte comparison.
return otherValue.value == u.value
}

// String returns a summary representation of either the underlying Value,
// or UnknownValueString (`<unknown>`) when IsUnknown() returns true,
// or NullValueString (`<null>`) when IsNull() return true.
func (v Value) String() string {
if v.null {
func (u UUID) String() string {
if u.null {
return attr.NullValueString
}

if v.unknown {
if u.unknown {
return attr.UnknownValueString
}

return v.value
return u.value.String()
}

0 comments on commit 72743a5

Please sign in to comment.