Skip to content

Commit

Permalink
feat(schema): add methods for proto <> schema conversions (#72)
Browse files Browse the repository at this point in the history
* add toproto and fromproto

* refactor

* add tests

* go mod tidy

* add error

* add clarifying comment

* fix comment

* undo

* undo
  • Loading branch information
raulb authored Jul 1, 2024
1 parent 0daeaaf commit 3948a38
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
2 changes: 2 additions & 0 deletions proto/schema/v1/schema.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ syntax = "proto3";

package schema.v1;

option go_package = "github.com/conduitio/conduit-commons/proto/schema/v1";

// Schema is a representation of a schema in the schema registry.
message Schema {
enum Type {
Expand Down
20 changes: 20 additions & 0 deletions schema/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright © 2024 Meroxa, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema

import "errors"

// errInvalidProtoIsNil is returned when trying to convert a schema object to a proto schema, and the proto is nil.
var errInvalidProtoIsNil = errors.New("invalid proto: nil")
63 changes: 63 additions & 0 deletions schema/proto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright © 2024 Meroxa, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema

import (
schemav1 "github.com/conduitio/conduit-commons/proto/schema/v1"
)

func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
var cTypes [1]struct{}
// Compatibility between the schema type in conduit-commons and the Protobuf schema type
_ = cTypes[int(TypeAvro)-int(schemav1.Schema_TYPE_AVRO)]
}

// -- From Proto To Schema ----------------------------------------------------

// FromProto takes data from the supplied proto object and populates the
// receiver. If the proto object is nil, the receiver is set to its zero value.
// If the function returns an error, the receiver could be partially populated.
func (s *Schema) FromProto(proto *schemav1.Schema) error {
if proto == nil {
*s = Schema{}
return nil
}

s.Subject = proto.Subject
s.Version = int(proto.Version)
s.Type = Type(proto.Type)
s.Bytes = proto.Bytes

return nil
}

// -- From Schema To Proto ----------------------------------------------------

// ToProto takes data from the receiver and populates the supplied proto object.
// If the function returns an error, the proto object could be partially
// populated.
func (s *Schema) ToProto(proto *schemav1.Schema) error {
if proto == nil {
return errInvalidProtoIsNil
}

proto.Subject = s.Subject
proto.Version = int32(s.Version)
proto.Type = schemav1.Schema_Type(s.Type)
proto.Bytes = s.Bytes

return nil
}
95 changes: 95 additions & 0 deletions schema/proto_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright © 2024 Meroxa, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema

import (
"testing"

schemav1 "github.com/conduitio/conduit-commons/proto/schema/v1"
"github.com/matryer/is"
)

func TestSchema_FromProto(t *testing.T) {
is := is.New(t)

s1 := &schemav1.Schema{
Subject: "subject",
Version: 1,
Type: schemav1.Schema_TYPE_AVRO,
Bytes: []byte("bytes"),
}

want := Schema{
Subject: "subject",
Version: 1,
Type: TypeAvro,
Bytes: []byte("bytes"),
}

var got Schema
err := got.FromProto(s1)
is.NoErr(err)
is.Equal(got, want)
}

func TestSchema_ToProto(t *testing.T) {
is := is.New(t)

testCases := []struct {
name string
in *schemav1.Schema
want *schemav1.Schema
wantErr error
}{
{
name: "when proto object is nil",
in: nil,
want: nil,
wantErr: errInvalidProtoIsNil,
},
{
name: "when proto object is not nil",
in: &schemav1.Schema{},
want: &schemav1.Schema{
Subject: "subject",
Version: 1,
Type: schemav1.Schema_TYPE_AVRO,
Bytes: []byte("bytes"),
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
is := is.New(t)

s1 := Schema{
Subject: "subject",
Version: 1,
Type: TypeAvro,
Bytes: []byte("bytes"),
}

err := s1.ToProto(tc.in)

if tc.wantErr == nil {
is.NoErr(err)
is.Equal(tc.in, tc.want)
} else {
is.Equal(err.Error(), tc.wantErr.Error())
}
})
}
}

0 comments on commit 3948a38

Please sign in to comment.