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 CQRS marshalers #78

Merged
merged 6 commits into from
May 25, 2019
Merged
Show file tree
Hide file tree
Changes from 5 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: 6 additions & 1 deletion components/cqrs/marshaler_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
)

type JSONMarshaler struct {
NewUUID func() string
NewUUID func() string
GenerateName func(v interface{}) string
}

func (m JSONMarshaler) Marshal(v interface{}) (*message.Message, error) {
Expand Down Expand Up @@ -40,6 +41,10 @@ func (JSONMarshaler) Unmarshal(msg *message.Message, v interface{}) (err error)
}

func (m JSONMarshaler) Name(cmdOrEvent interface{}) string {
if m.GenerateName != nil {
return m.GenerateName(cmdOrEvent)
}

return ObjectName(cmdOrEvent)
}

Expand Down
7 changes: 6 additions & 1 deletion components/cqrs/marshaler_protobuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
)

type ProtobufMarshaler struct {
NewUUID func() string
NewUUID func() string
GenerateName func(v interface{}) string
}

type NoProtoMessageError struct {
Expand Down Expand Up @@ -61,6 +62,10 @@ func (ProtobufMarshaler) Unmarshal(msg *message.Message, v interface{}) (err err
}

func (m ProtobufMarshaler) Name(cmdOrEvent interface{}) string {
if m.GenerateName != nil {
return m.GenerateName(cmdOrEvent)
}

return ObjectName(cmdOrEvent)
}

Expand Down
42 changes: 42 additions & 0 deletions components/cqrs/name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package cqrs

import (
"fmt"
"strings"
)

// ObjectName name returns object name in format [package].[type name].
// It ignores if the value is a pointer or not.
func ObjectName(v interface{}) string {
s := fmt.Sprintf("%T", v)
s = strings.TrimLeft(s, "*")

return s
}

// StructName name returns struct name in format [type name].
// It ignores if the value is a pointer or not.
func StructName(v interface{}) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe ObjectNameWithoutPackage? it is pretty long, but explicit :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was rather thinking about renaming ObjectName to FullyQualifiedStructName and leave this as is, but ObjectNameWithoutPackage works as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, like I like the idea of FullyQualifiedStructName :)

segments := strings.Split(fmt.Sprintf("%T", v), ".")

return segments[len(segments)-1]
}

type namedMessage interface {
roblaszczak marked this conversation as resolved.
Show resolved Hide resolved
Name() string
}

// MessageName returns the name from a message implementing the following interface:
// type namedMessage interface {
// Name() string
// }
// It ignores if the value is a pointer or not.
func MessageName(fallback func(v interface{}) string) func(v interface{}) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about NamedObject?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the pattern I suggested above, this could be NamedStruct, but if we stick with object, NamedObject works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return func(v interface{}) string {
if v, ok := v.(namedMessage); ok {
return v.Name()
}

return fallback(v)
}
}
49 changes: 49 additions & 0 deletions components/cqrs/name_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cqrs_test

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/ThreeDotsLabs/watermill/components/cqrs"
)

func TestObjectName(t *testing.T) {
type Object struct{}

assert.Equal(t, "cqrs_test.Object", cqrs.ObjectName(Object{}))
assert.Equal(t, "cqrs_test.Object", cqrs.ObjectName(&Object{}))
}

func BenchmarkObjectName(b *testing.B) {
type Object struct{}
o := Object{}

for i := 0; i < b.N; i++ {
cqrs.ObjectName(o)
}
}

func TestStructName(t *testing.T) {
type Object struct{}

assert.Equal(t, "Object", cqrs.StructName(Object{}))
assert.Equal(t, "Object", cqrs.StructName(&Object{}))
}

func TestMessageName(t *testing.T) {
assert.Equal(t, "named object", cqrs.MessageName(cqrs.StructName)(namedObject{}))
assert.Equal(t, "named object", cqrs.MessageName(cqrs.StructName)(&namedObject{}))

// Test fallback
type Object struct{}

assert.Equal(t, "Object", cqrs.MessageName(cqrs.StructName)(Object{}))
assert.Equal(t, "Object", cqrs.MessageName(cqrs.StructName)(&Object{}))
}

type namedObject struct{}

func (namedObject) Name() string {
return "named object"
}
11 changes: 0 additions & 11 deletions components/cqrs/object.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package cqrs

import (
"fmt"
"reflect"
"strings"
)

func isPointer(v interface{}) error {
Expand All @@ -23,12 +21,3 @@ type NonPointerError struct {
func (e NonPointerError) Error() string {
return "non-pointer command: " + e.Type.String() + ", handler.NewCommand() should return pointer to the command"
}

// ObjectName name returns object name in format [package].[type name].
// It ignores if the value is a pointer or not.
func ObjectName(v interface{}) string {
s := fmt.Sprintf("%T", v)
s = strings.TrimLeft(s, "*")

return s
}
24 changes: 0 additions & 24 deletions components/cqrs/object_test.go

This file was deleted.