diff --git a/proto/schema/v1/schema.proto b/proto/schema/v1/schema.proto index ab76e6d..cb8d049 100644 --- a/proto/schema/v1/schema.proto +++ b/proto/schema/v1/schema.proto @@ -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 { diff --git a/schema/errors.go b/schema/errors.go new file mode 100644 index 0000000..716b7bc --- /dev/null +++ b/schema/errors.go @@ -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") diff --git a/schema/proto.go b/schema/proto.go new file mode 100644 index 0000000..0cc3bd6 --- /dev/null +++ b/schema/proto.go @@ -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 +} diff --git a/schema/proto_test.go b/schema/proto_test.go new file mode 100644 index 0000000..81192bb --- /dev/null +++ b/schema/proto_test.go @@ -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()) + } + }) + } +}