Skip to content

Commit

Permalink
Add ToProto() and FromProto().
Browse files Browse the repository at this point in the history
  • Loading branch information
jmalloc committed Aug 15, 2024
1 parent 660f84a commit 4836892
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 120 deletions.
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 @@ func marshalApplication(in configkit.Application) (*configspec.Application, erro
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 @@ func unmarshalApplication(in *configspec.Application) (configkit.Application, er
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 @@ func marshalHandler(in configkit.Handler) (*configspec.Handler, error) {

// 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 @@ func marshalNameRoles(in message.NameRoles) (map[string]configspec.MessageRole,
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 @@ func unmarshalNameRoles(in map[string]configspec.MessageRole) (message.NameRoles
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 @@ func marshalIdentity(in configkit.Identity) (*configspec.Identity, error) {
}, 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 @@ func unmarshalMessageRole(r configspec.MessageRole) (message.Role, error) {
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

0 comments on commit 4836892

Please sign in to comment.