Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ToProto() and FromProto(). #296

Merged
merged 1 commit into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog], and this project adheres to
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
[semantic versioning]: https://semver.org/spec/v2.0.0.html

## [Unreleased]

### Added

- Added `ToProto()` and `FromProto()` to convert application configurations to
and from their protocol buffers representations.

## [0.13.2] - 2024-08-12

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (c *Client) ListApplications(

var configs []configkit.Application
for _, in := range res.GetApplications() {
out, err := unmarshalApplication(in)
out, err := configkit.FromProto(in)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func NewServer(apps ...configkit.Application) *Server {
s := &Server{}

for _, in := range apps {
out, err := marshalApplication(in)
out, err := configkit.ToProto(in)
if err != nil {
panic(err)
}
Expand Down
3 changes: 2 additions & 1 deletion api/server_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api
package api_test

import (
. "github.com/dogmatiq/configkit/api"
"github.com/dogmatiq/configkit/internal/entity"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down
5 changes: 5 additions & 0 deletions internal/entity/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Package entity provides internal implementations of the entities defined in
// the configkit package.
//
// deprecated: Packages should define their own implementations instead.
package entity
182 changes: 130 additions & 52 deletions api/marshaling.go → marshal.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package api
package configkit

import (
"context"
"errors"
"fmt"

"github.com/dogmatiq/configkit"
"github.com/dogmatiq/configkit/internal/entity"
"github.com/dogmatiq/configkit/message"
"github.com/dogmatiq/interopspec/configspec"
)

// marshalApplication marshals an application config to its protobuf
// ToProto converts an application configuration to its protocol buffers
// representation.
func marshalApplication(in configkit.Application) (*configspec.Application, error) {
func ToProto(in Application) (*configspec.Application, error) {
out := &configspec.Application{}

var err error
Expand All @@ -38,25 +37,19 @@
return out, nil
}

// unmarshalApplication unmarshals an application config from its protobuf
// FromProto converts an application configuration from its protocol buffers
// representation.
func unmarshalApplication(in *configspec.Application) (configkit.Application, error) {
out := &entity.Application{
MessageNamesValue: configkit.EntityMessageNames{
Produced: message.NameRoles{},
Consumed: message.NameRoles{},
},
HandlersValue: configkit.HandlerSet{},
}
func FromProto(in *configspec.Application) (Application, error) {
out := &unmarshaledApplication{}

var err error
out.IdentityValue, err = unmarshalIdentity(in.GetIdentity())
out.ident, err = unmarshalIdentity(in.GetIdentity())
if err != nil {
return nil, err
}

out.TypeNameValue = in.GetGoType()
if out.TypeNameValue == "" {
out.typeName = in.GetGoType()
if out.typeName == "" {
return nil, errors.New("application type name is empty")
}

Expand All @@ -66,22 +59,31 @@
return nil, err
}

out.HandlersValue.Add(hOut)
if out.handlers == nil {
out.handlers = HandlerSet{}

Check warning on line 63 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L62-L63

Added lines #L62 - L63 were not covered by tests
}
out.handlers.Add(hOut)

Check warning on line 65 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L65

Added line #L65 was not covered by tests

for n, r := range hOut.MessageNames().Produced {
out.MessageNamesValue.Produced[n] = r
if out.names.Produced == nil {
out.names.Produced = message.NameRoles{}

Check warning on line 69 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L68-L69

Added lines #L68 - L69 were not covered by tests
}
out.names.Produced[n] = r

Check warning on line 71 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L71

Added line #L71 was not covered by tests
}

for n, r := range hOut.MessageNames().Consumed {
out.MessageNamesValue.Consumed[n] = r
if out.names.Consumed == nil {
out.names.Consumed = message.NameRoles{}

Check warning on line 76 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L75-L76

Added lines #L75 - L76 were not covered by tests
}
out.names.Consumed[n] = r

Check warning on line 78 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L78

Added line #L78 was not covered by tests
}
}

return out, nil
}

// marshalHandler marshals a handler config to its protobuf representation.
func marshalHandler(in configkit.Handler) (*configspec.Handler, error) {
func marshalHandler(in Handler) (*configspec.Handler, error) {
out := &configspec.Handler{
IsDisabled: in.IsDisabled(),
}
Expand Down Expand Up @@ -118,37 +120,33 @@

// unmarshalHandler unmarshals a handler configuration from its protocol buffers
// representation.
func unmarshalHandler(in *configspec.Handler) (configkit.Handler, error) {
out := &entity.Handler{
MessageNamesValue: configkit.EntityMessageNames{
Produced: message.NameRoles{},
Consumed: message.NameRoles{},
},
IsDisabledValue: in.GetIsDisabled(),
func unmarshalHandler(in *configspec.Handler) (Handler, error) {
out := &unmarshaledHandler{
isDisabled: in.GetIsDisabled(),
}

var err error
out.IdentityValue, err = unmarshalIdentity(in.GetIdentity())
out.ident, err = unmarshalIdentity(in.GetIdentity())
if err != nil {
return nil, err
}

out.TypeNameValue = in.GetGoType()
if out.TypeNameValue == "" {
out.typeName = in.GetGoType()
if out.typeName == "" {
return nil, errors.New("handler type name is empty")
}

out.HandlerTypeValue, err = unmarshalHandlerType(in.GetType())
out.handlerType, err = unmarshalHandlerType(in.GetType())
if err != nil {
return nil, err
}

out.MessageNamesValue.Produced, err = unmarshalNameRoles(in.GetProducedMessages())
out.names.Produced, err = unmarshalNameRoles(in.GetProducedMessages())
if err != nil {
return nil, err
}

out.MessageNamesValue.Consumed, err = unmarshalNameRoles(in.GetConsumedMessages())
out.names.Consumed, err = unmarshalNameRoles(in.GetConsumedMessages())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -178,7 +176,7 @@
return out, nil
}

// marshalNameRoles unmarshals a message.NameRoles collection from
// unmarshalNameRoles unmarshals a message.NameRoles collection from
// its protocol buffers representation.
func unmarshalNameRoles(in map[string]configspec.MessageRole) (message.NameRoles, error) {
out := message.NameRoles{}
Expand All @@ -201,9 +199,9 @@
return out, nil
}

// marshalIdentity marshals a configkit.Identity to its protocol buffers
// marshalIdentity marshals a Identity to its protocol buffers
// representation.
func marshalIdentity(in configkit.Identity) (*configspec.Identity, error) {
func marshalIdentity(in Identity) (*configspec.Identity, error) {
if err := in.Validate(); err != nil {
return nil, err
}
Expand All @@ -214,46 +212,46 @@
}, nil
}

// unmarshalIdentity unmarshals a configkit.Identity from its protocol buffers
// unmarshalIdentity unmarshals a Identity from its protocol buffers
// representation.
func unmarshalIdentity(in *configspec.Identity) (configkit.Identity, error) {
return configkit.NewIdentity(
func unmarshalIdentity(in *configspec.Identity) (Identity, error) {
return NewIdentity(
in.GetName(),
in.GetKey(),
)
}

// marshalHandlerType marshals a configkit.HandlerType to its protocol buffers
// marshalHandlerType marshals a HandlerType to its protocol buffers
// representation.
func marshalHandlerType(t configkit.HandlerType) (configspec.HandlerType, error) {
func marshalHandlerType(t HandlerType) (configspec.HandlerType, error) {
if err := t.Validate(); err != nil {
return configspec.HandlerType_UNKNOWN_HANDLER_TYPE, err
}

switch t {
case configkit.AggregateHandlerType:
case AggregateHandlerType:
return configspec.HandlerType_AGGREGATE, nil
case configkit.ProcessHandlerType:
case ProcessHandlerType:
return configspec.HandlerType_PROCESS, nil
case configkit.IntegrationHandlerType:
case IntegrationHandlerType:
return configspec.HandlerType_INTEGRATION, nil
default: // configkit.ProjectionHandlerType
default: // ProjectionHandlerType
return configspec.HandlerType_PROJECTION, nil
}
}

// unmarshalHandlerType unmarshals a configkit.HandlerType from its protocol
// unmarshalHandlerType unmarshals a HandlerType from its protocol
// buffers representation.
func unmarshalHandlerType(t configspec.HandlerType) (configkit.HandlerType, error) {
func unmarshalHandlerType(t configspec.HandlerType) (HandlerType, error) {
switch t {
case configspec.HandlerType_AGGREGATE:
return configkit.AggregateHandlerType, nil
return AggregateHandlerType, nil
case configspec.HandlerType_PROCESS:
return configkit.ProcessHandlerType, nil
return ProcessHandlerType, nil
case configspec.HandlerType_INTEGRATION:
return configkit.IntegrationHandlerType, nil
return IntegrationHandlerType, nil
case configspec.HandlerType_PROJECTION:
return configkit.ProjectionHandlerType, nil
return ProjectionHandlerType, nil
default:
return "", fmt.Errorf("unknown handler type: %#v", t)
}
Expand Down Expand Up @@ -290,3 +288,83 @@
return "", fmt.Errorf("unknown message role: %#v", r)
}
}

// unmarshaledApplication is an implementation of [Application] that has been
// produced by unmarshaling a configuration.
type unmarshaledApplication struct {
ident Identity
names EntityMessageNames
typeName string
handlers HandlerSet
}

func (a *unmarshaledApplication) Identity() Identity {
return a.ident
}

func (a *unmarshaledApplication) MessageNames() EntityMessageNames {
return a.names

Check warning on line 306 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L305-L306

Added lines #L305 - L306 were not covered by tests
}

func (a *unmarshaledApplication) TypeName() string {
return a.typeName
}

func (a *unmarshaledApplication) AcceptVisitor(ctx context.Context, v Visitor) error {
return v.VisitApplication(ctx, a)

Check warning on line 314 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L313-L314

Added lines #L313 - L314 were not covered by tests
}

func (a *unmarshaledApplication) Handlers() HandlerSet {
return a.handlers
}

// unmarshaledHandler is an implementation of [Handler] that has been produced
// by unmarshaling a configuration.
type unmarshaledHandler struct {
ident Identity
names EntityMessageNames
typeName string
handlerType HandlerType
isDisabled bool
}

// Identity returns the identity of the entity.
func (h *unmarshaledHandler) Identity() Identity {
return h.ident
}

// MessageNames returns information about the messages used by the entity.
func (h *unmarshaledHandler) MessageNames() EntityMessageNames {
return h.names
}

// TypeName returns the fully-qualified type name of the entity.
func (h *unmarshaledHandler) TypeName() string {
return h.typeName
}

// HandlerType returns the type of handler.
func (h *unmarshaledHandler) HandlerType() HandlerType {
return h.handlerType
}

// IsDisabled returns true if the handler is disabled.
func (h *unmarshaledHandler) IsDisabled() bool {
return h.isDisabled
}

// AcceptVisitor calls the appropriate method on v for this entity type.
func (h *unmarshaledHandler) AcceptVisitor(ctx context.Context, v Visitor) error {
h.handlerType.MustValidate()

Check warning on line 358 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L357-L358

Added lines #L357 - L358 were not covered by tests

switch h.handlerType {
case AggregateHandlerType:
return v.VisitAggregate(ctx, h)
case ProcessHandlerType:
return v.VisitProcess(ctx, h)
case IntegrationHandlerType:
return v.VisitIntegration(ctx, h)
default: // ProjectionHandlerType
return v.VisitProjection(ctx, h)

Check warning on line 368 in marshal.go

View check run for this annotation

Codecov / codecov/patch

marshal.go#L360-L368

Added lines #L360 - L368 were not covered by tests
}
}
Loading