Repository: ariga/atlas
Pull request #286 (2021-12-06 18:04:37)

schema/schemaspec/schemahcl: renaming the Unmarshaler type to state 
and adding the MarshalSpec method.


Patch:
diff --git a/schema/schemaspec/schemahcl/hcl.go b/schema/schemaspec/schemahcl/hcl.go
index 79b77308..8005fae1 100644
--- a/schema/schemaspec/schemahcl/hcl.go
+++ b/schema/schemaspec/schemahcl/hcl.go
@@ -19,18 +19,12 @@ import (
 
 var (
 	// Marshal returns the Atlas HCL encoding of v.
-	Marshal = schemaspec.MarshalerFunc(func(v interface{}) ([]byte, error) {
-		r := &schemaspec.Resource{}
-		if err := r.Scan(v); err != nil {
-			return nil, fmt.Errorf("schemahcl: failed scanning %T to resource: %w", v, err)
-		}
-		return encode(r)
-	})
+	Marshal = schemaspec.MarshalerFunc(New().MarshalSpec)
 )
 
 var (
 	// Unmarshal parses the Atlas HCL-encoded data and stores the result in the target.
-	Unmarshal = schemaspec.UnmarshalerFunc(NewUnmarshaler().UnmarshalSpec)
+	Unmarshal = schemaspec.UnmarshalerFunc(New().UnmarshalSpec)
 )
 
 type (
@@ -38,15 +32,25 @@ type (
 		Body hcl.Body `hcl:",remain"`
 	}
 
-	// Unmarshaler implements schemaspec.Unmarshaler
-	Unmarshaler struct {
+	// state implements schemaspec.Unmarshaler and schemaspec.Marshaler for Atlas HCL syntax
+	// and stores a configuration for these operations.
+	state struct {
 		config *Config
 	}
 )
 
+// MarshalSpec implements schemaspec.Marshaler for Atlas HCL documents.
+func (s *state) MarshalSpec(v interface{}) ([]byte, error) {
+	r := &schemaspec.Resource{}
+	if err := r.Scan(v); err != nil {
+		return nil, fmt.Errorf("schemahcl: failed scanning %T to resource: %w", v, err)
+	}
+	return encode(r)
+}
+
 // UnmarshalSpec implements schemaspec.Unmarshaler.
-func (u *Unmarshaler) UnmarshalSpec(data []byte, v interface{}) error {
-	spec, err := decode(u.config.ctx, data)
+func (s *state) UnmarshalSpec(data []byte, v interface{}) error {
+	spec, err := decode(s.config.ctx, data)
 	if err != nil {
 		return fmt.Errorf("schemahcl: failed decoding: %w", err)
 	}
diff --git a/schema/schemaspec/schemahcl/opts.go b/schema/schemaspec/schemahcl/opts.go
index 842b9cc9..79981084 100644
--- a/schema/schemaspec/schemahcl/opts.go
+++ b/schema/schemaspec/schemahcl/opts.go
@@ -19,8 +19,8 @@ type (
 	Option func(*Config)
 )
 
-// NewUnmarshaler returns a schemaspec.Unmarshaler configured with options.
-func NewUnmarshaler(opts ...Option) *Unmarshaler {
+// New returns a state configured with options.
+func New(opts ...Option) *state {
 	cfg := &Config{
 		ctx: &hcl.EvalContext{
 			Variables: make(map[string]cty.Value),
@@ -30,7 +30,7 @@ func NewUnmarshaler(opts ...Option) *Unmarshaler {
 	for _, opt := range opts {
 		opt(cfg)
 	}
-	return &Unmarshaler{config: cfg}
+	return &state{config: cfg}
 }
 
 // EvalContext configures an unmarshaler to decode with an *hcl.EvalContext.


Test patch:
diff --git a/schema/schemaspec/schemahcl/context_test.go b/schema/schemaspec/schemahcl/context_test.go
index 8d7cff9a..1493f263 100644
--- a/schema/schemaspec/schemahcl/context_test.go
+++ b/schema/schemaspec/schemahcl/context_test.go
@@ -339,14 +339,14 @@ x = from_ctx
 	var test struct {
 		X int `spec:"x"`
 	}
-	unmarshaler := NewUnmarshaler(
+	s := New(
 		EvalContext(&hcl.EvalContext{
 			Variables: map[string]cty.Value{
 				"from_ctx": cty.NumberIntVal(42),
 			},
 		}),
 	)
-	err := unmarshaler.UnmarshalSpec([]byte(f), &test)
+	err := s.UnmarshalSpec([]byte(f), &test)
 	require.NoError(t, err)
 	require.EqualValues(t, 42, test.X)
 }
@@ -357,7 +357,7 @@ first = int
 second = bool
 sized = varchar(255)
 `
-	unmarshaler := NewUnmarshaler(
+	s := New(
 		WithTypes(
 			[]*schemaspec.TypeSpec{
 				{Name: "int", T: "int"},
@@ -377,7 +377,7 @@ sized = varchar(255)
 		Second  *schemaspec.Type `spec:"second"`
 		Varchar *schemaspec.Type `spec:"sized"`
 	}
-	err := unmarshaler.UnmarshalSpec([]byte(f), &test)
+	err := s.UnmarshalSpec([]byte(f), &test)
 	require.NoError(t, err)
 	require.EqualValues(t, "int", test.First.T)
 	require.EqualValues(t, "bool", test.Second.T)