From 5405e49373f05eadc15a6a3a6e88f5ade704a8ee Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Sat, 18 May 2019 10:30:01 +0200 Subject: [PATCH 1/6] Add name marshaler --- components/cqrs/marshaler_name.go | 55 +++++++++++++++++++++++ components/cqrs/marshaler_name_test.go | 61 ++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 components/cqrs/marshaler_name.go create mode 100644 components/cqrs/marshaler_name_test.go diff --git a/components/cqrs/marshaler_name.go b/components/cqrs/marshaler_name.go new file mode 100644 index 000000000..276f3ef6f --- /dev/null +++ b/components/cqrs/marshaler_name.go @@ -0,0 +1,55 @@ +package cqrs + +import ( + "github.com/ThreeDotsLabs/watermill/message" +) + +// NameMarshaler retrieves the name from a message implementing the following interface: +// type namedMessage interface { +// Name() string +// } +// +// It wraps another marshaler which takes care of the message serialization/deserialization. +// If none provided, it falls back to JSON marshaler. +type NameMarshaler struct { + Marshaler CommandEventMarshaler +} + +func (m *NameMarshaler) marshaler() CommandEventMarshaler { + if m.Marshaler == nil { + return JSONMarshaler{} + } + + return m.Marshaler +} + +type namedMessage interface { + Name() string +} + +func (m *NameMarshaler) Marshal(v interface{}) (*message.Message, error) { + msg, err := m.marshaler().Marshal(v) + if err != nil { + return nil, err + } + + msg.Metadata.Set("name", m.Name(v)) + + return msg, nil +} + +func (m *NameMarshaler) Unmarshal(msg *message.Message, v interface{}) error { + return m.marshaler().Unmarshal(msg, v) +} + +func (m *NameMarshaler) Name(v interface{}) string { + if v, ok := v.(namedMessage); ok { + return v.Name() + } + + return m.marshaler().Name(v) +} + +func (m *NameMarshaler) NameFromMessage(msg *message.Message) string { + return msg.Metadata.Get("name") +} diff --git a/components/cqrs/marshaler_name_test.go b/components/cqrs/marshaler_name_test.go new file mode 100644 index 000000000..fafc76c08 --- /dev/null +++ b/components/cqrs/marshaler_name_test.go @@ -0,0 +1,61 @@ +package cqrs_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/ThreeDotsLabs/watermill" + "github.com/ThreeDotsLabs/watermill/components/cqrs" +) + +type NamedEvent struct { + TestEvent +} + +func (e NamedEvent) Name() string { + return "testEvent" +} + +func TestNameMarshaler(t *testing.T) { + eventToMarshal := NamedEvent{ + TestEvent: TestEvent{ + ID: watermill.NewULID(), + When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), + }, + } + + marshaler := &cqrs.NameMarshaler{} + + msg, err := marshaler.Marshal(eventToMarshal) + require.NoError(t, err) + + assert.Equal(t, "testEvent", marshaler.NameFromMessage(msg)) + + eventToUnmarshal := NamedEvent{} + err = marshaler.Unmarshal(msg, &eventToUnmarshal) + require.NoError(t, err) + + assert.EqualValues(t, eventToMarshal, eventToUnmarshal) + assert.Equal(t, "testEvent", marshaler.Name(eventToUnmarshal)) +} + +func TestNameMarshaler_NotNamedMessage(t *testing.T) { + eventToMarshal := TestEvent{ + ID: watermill.NewULID(), + When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), + } + + marshaler := &cqrs.NameMarshaler{} + + msg, err := marshaler.Marshal(eventToMarshal) + require.NoError(t, err) + + eventToUnmarshal := TestEvent{} + err = marshaler.Unmarshal(msg, &eventToUnmarshal) + require.NoError(t, err) + + assert.EqualValues(t, eventToMarshal, eventToUnmarshal) +} From a476006c1c1b33b0d8b9c9373efb5c8b872f8875 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Sun, 19 May 2019 15:21:43 +0200 Subject: [PATCH 2/6] Add struct name marshaler --- components/cqrs/marshaler_structname.go | 49 ++++++++++++++++++++ components/cqrs/marshaler_structname_test.go | 33 +++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 components/cqrs/marshaler_structname.go create mode 100644 components/cqrs/marshaler_structname_test.go diff --git a/components/cqrs/marshaler_structname.go b/components/cqrs/marshaler_structname.go new file mode 100644 index 000000000..5093917b7 --- /dev/null +++ b/components/cqrs/marshaler_structname.go @@ -0,0 +1,49 @@ +package cqrs + +import ( + "fmt" + "strings" + + "github.com/ThreeDotsLabs/watermill/message" +) + +// StructNameMarshaler uses the struct name (without the package) as the message name. +// +// It wraps another marshaler which takes care of the message serialization/deserialization. +// If none provided, it falls back to JSON marshaler. +type StructNameMarshaler struct { + Marshaler CommandEventMarshaler +} + +func (m *StructNameMarshaler) marshaler() CommandEventMarshaler { + if m.Marshaler == nil { + return JSONMarshaler{} + } + + return m.Marshaler +} + +func (m *StructNameMarshaler) Marshal(v interface{}) (*message.Message, error) { + msg, err := m.marshaler().Marshal(v) + if err != nil { + return nil, err + } + + msg.Metadata.Set("name", m.Name(v)) + + return msg, nil +} + +func (m *StructNameMarshaler) Unmarshal(msg *message.Message, v interface{}) error { + return m.marshaler().Unmarshal(msg, v) +} + +func (m *StructNameMarshaler) Name(v interface{}) string { + segments := strings.Split(fmt.Sprintf("%T", v), ".") + + return segments[len(segments)-1] +} + +func (m *StructNameMarshaler) NameFromMessage(msg *message.Message) string { + return msg.Metadata.Get("name") +} diff --git a/components/cqrs/marshaler_structname_test.go b/components/cqrs/marshaler_structname_test.go new file mode 100644 index 000000000..aade15ddd --- /dev/null +++ b/components/cqrs/marshaler_structname_test.go @@ -0,0 +1,33 @@ +package cqrs_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/ThreeDotsLabs/watermill" + "github.com/ThreeDotsLabs/watermill/components/cqrs" +) + +func TestStructNameMarshaler(t *testing.T) { + eventToMarshal := TestEvent{ + ID: watermill.NewULID(), + When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), + } + + marshaler := &cqrs.StructNameMarshaler{} + + msg, err := marshaler.Marshal(eventToMarshal) + require.NoError(t, err) + + assert.Equal(t, "TestEvent", marshaler.NameFromMessage(msg)) + + eventToUnmarshal := TestEvent{} + err = marshaler.Unmarshal(msg, &eventToUnmarshal) + require.NoError(t, err) + + assert.EqualValues(t, eventToMarshal, eventToUnmarshal) + assert.Equal(t, "TestEvent", marshaler.Name(eventToUnmarshal)) +} From 9801b33ada6bb5812159fff48b619f9b5758ab7e Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Thu, 23 May 2019 11:38:24 +0200 Subject: [PATCH 3/6] Extract name generator functions --- components/cqrs/marshaler_name.go | 4 -- components/cqrs/name.go | 40 +++++++++++++++++++ .../cqrs/{object_test.go => name_test.go} | 21 +++++++++- components/cqrs/object.go | 11 ----- 4 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 components/cqrs/name.go rename components/cqrs/{object_test.go => name_test.go} (51%) diff --git a/components/cqrs/marshaler_name.go b/components/cqrs/marshaler_name.go index 276f3ef6f..914f3b8b7 100644 --- a/components/cqrs/marshaler_name.go +++ b/components/cqrs/marshaler_name.go @@ -23,10 +23,6 @@ func (m *NameMarshaler) marshaler() CommandEventMarshaler { return m.Marshaler } -type namedMessage interface { - Name() string -} - func (m *NameMarshaler) Marshal(v interface{}) (*message.Message, error) { msg, err := m.marshaler().Marshal(v) if err != nil { diff --git a/components/cqrs/name.go b/components/cqrs/name.go new file mode 100644 index 000000000..78fe03619 --- /dev/null +++ b/components/cqrs/name.go @@ -0,0 +1,40 @@ +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 { + segments := strings.Split(fmt.Sprintf("%T", v), ".") + + return segments[len(segments)-1] +} + +type namedMessage interface { + 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(v interface{}) string { + if v, ok := v.(namedMessage); ok { + return v.Name() + } + + return "" +} diff --git a/components/cqrs/object_test.go b/components/cqrs/name_test.go similarity index 51% rename from components/cqrs/object_test.go rename to components/cqrs/name_test.go index 1871a350b..5080778a0 100644 --- a/components/cqrs/object_test.go +++ b/components/cqrs/name_test.go @@ -3,8 +3,9 @@ package cqrs_test import ( "testing" - "github.com/ThreeDotsLabs/watermill/components/cqrs" "github.com/stretchr/testify/assert" + + "github.com/ThreeDotsLabs/watermill/components/cqrs" ) func TestObjectName(t *testing.T) { @@ -22,3 +23,21 @@ func BenchmarkObjectName(b *testing.B) { 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(namedObject{})) + assert.Equal(t, "named object", cqrs.MessageName(&namedObject{})) +} + +type namedObject struct{} + +func (namedObject) Name() string { + return "named object" +} diff --git a/components/cqrs/object.go b/components/cqrs/object.go index 538f870f1..1575fe118 100644 --- a/components/cqrs/object.go +++ b/components/cqrs/object.go @@ -1,9 +1,7 @@ package cqrs import ( - "fmt" "reflect" - "strings" ) func isPointer(v interface{}) error { @@ -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 -} From aee4af59fd7efcede0f551bc635a09b80704bc17 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Thu, 23 May 2019 11:40:41 +0200 Subject: [PATCH 4/6] Replace name marshalers with name generator functions --- components/cqrs/marshaler_json.go | 7 ++- components/cqrs/marshaler_name.go | 51 ---------------- components/cqrs/marshaler_name_test.go | 61 -------------------- components/cqrs/marshaler_protobuf.go | 7 ++- components/cqrs/marshaler_structname.go | 49 ---------------- components/cqrs/marshaler_structname_test.go | 33 ----------- 6 files changed, 12 insertions(+), 196 deletions(-) delete mode 100644 components/cqrs/marshaler_name.go delete mode 100644 components/cqrs/marshaler_name_test.go delete mode 100644 components/cqrs/marshaler_structname.go delete mode 100644 components/cqrs/marshaler_structname_test.go diff --git a/components/cqrs/marshaler_json.go b/components/cqrs/marshaler_json.go index ec759b45f..a2fd00337 100644 --- a/components/cqrs/marshaler_json.go +++ b/components/cqrs/marshaler_json.go @@ -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) { @@ -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) } diff --git a/components/cqrs/marshaler_name.go b/components/cqrs/marshaler_name.go deleted file mode 100644 index 914f3b8b7..000000000 --- a/components/cqrs/marshaler_name.go +++ /dev/null @@ -1,51 +0,0 @@ -package cqrs - -import ( - "github.com/ThreeDotsLabs/watermill/message" -) - -// NameMarshaler retrieves the name from a message implementing the following interface: -// type namedMessage interface { -// Name() string -// } -// -// It wraps another marshaler which takes care of the message serialization/deserialization. -// If none provided, it falls back to JSON marshaler. -type NameMarshaler struct { - Marshaler CommandEventMarshaler -} - -func (m *NameMarshaler) marshaler() CommandEventMarshaler { - if m.Marshaler == nil { - return JSONMarshaler{} - } - - return m.Marshaler -} - -func (m *NameMarshaler) Marshal(v interface{}) (*message.Message, error) { - msg, err := m.marshaler().Marshal(v) - if err != nil { - return nil, err - } - - msg.Metadata.Set("name", m.Name(v)) - - return msg, nil -} - -func (m *NameMarshaler) Unmarshal(msg *message.Message, v interface{}) error { - return m.marshaler().Unmarshal(msg, v) -} - -func (m *NameMarshaler) Name(v interface{}) string { - if v, ok := v.(namedMessage); ok { - return v.Name() - } - - return m.marshaler().Name(v) -} - -func (m *NameMarshaler) NameFromMessage(msg *message.Message) string { - return msg.Metadata.Get("name") -} diff --git a/components/cqrs/marshaler_name_test.go b/components/cqrs/marshaler_name_test.go deleted file mode 100644 index fafc76c08..000000000 --- a/components/cqrs/marshaler_name_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package cqrs_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/ThreeDotsLabs/watermill" - "github.com/ThreeDotsLabs/watermill/components/cqrs" -) - -type NamedEvent struct { - TestEvent -} - -func (e NamedEvent) Name() string { - return "testEvent" -} - -func TestNameMarshaler(t *testing.T) { - eventToMarshal := NamedEvent{ - TestEvent: TestEvent{ - ID: watermill.NewULID(), - When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), - }, - } - - marshaler := &cqrs.NameMarshaler{} - - msg, err := marshaler.Marshal(eventToMarshal) - require.NoError(t, err) - - assert.Equal(t, "testEvent", marshaler.NameFromMessage(msg)) - - eventToUnmarshal := NamedEvent{} - err = marshaler.Unmarshal(msg, &eventToUnmarshal) - require.NoError(t, err) - - assert.EqualValues(t, eventToMarshal, eventToUnmarshal) - assert.Equal(t, "testEvent", marshaler.Name(eventToUnmarshal)) -} - -func TestNameMarshaler_NotNamedMessage(t *testing.T) { - eventToMarshal := TestEvent{ - ID: watermill.NewULID(), - When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), - } - - marshaler := &cqrs.NameMarshaler{} - - msg, err := marshaler.Marshal(eventToMarshal) - require.NoError(t, err) - - eventToUnmarshal := TestEvent{} - err = marshaler.Unmarshal(msg, &eventToUnmarshal) - require.NoError(t, err) - - assert.EqualValues(t, eventToMarshal, eventToUnmarshal) -} diff --git a/components/cqrs/marshaler_protobuf.go b/components/cqrs/marshaler_protobuf.go index 0f9c4c40f..45cb9eb69 100644 --- a/components/cqrs/marshaler_protobuf.go +++ b/components/cqrs/marshaler_protobuf.go @@ -11,7 +11,8 @@ import ( ) type ProtobufMarshaler struct { - NewUUID func() string + NewUUID func() string + GenerateName func(v interface{}) string } type NoProtoMessageError struct { @@ -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) } diff --git a/components/cqrs/marshaler_structname.go b/components/cqrs/marshaler_structname.go deleted file mode 100644 index 5093917b7..000000000 --- a/components/cqrs/marshaler_structname.go +++ /dev/null @@ -1,49 +0,0 @@ -package cqrs - -import ( - "fmt" - "strings" - - "github.com/ThreeDotsLabs/watermill/message" -) - -// StructNameMarshaler uses the struct name (without the package) as the message name. -// -// It wraps another marshaler which takes care of the message serialization/deserialization. -// If none provided, it falls back to JSON marshaler. -type StructNameMarshaler struct { - Marshaler CommandEventMarshaler -} - -func (m *StructNameMarshaler) marshaler() CommandEventMarshaler { - if m.Marshaler == nil { - return JSONMarshaler{} - } - - return m.Marshaler -} - -func (m *StructNameMarshaler) Marshal(v interface{}) (*message.Message, error) { - msg, err := m.marshaler().Marshal(v) - if err != nil { - return nil, err - } - - msg.Metadata.Set("name", m.Name(v)) - - return msg, nil -} - -func (m *StructNameMarshaler) Unmarshal(msg *message.Message, v interface{}) error { - return m.marshaler().Unmarshal(msg, v) -} - -func (m *StructNameMarshaler) Name(v interface{}) string { - segments := strings.Split(fmt.Sprintf("%T", v), ".") - - return segments[len(segments)-1] -} - -func (m *StructNameMarshaler) NameFromMessage(msg *message.Message) string { - return msg.Metadata.Get("name") -} diff --git a/components/cqrs/marshaler_structname_test.go b/components/cqrs/marshaler_structname_test.go deleted file mode 100644 index aade15ddd..000000000 --- a/components/cqrs/marshaler_structname_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package cqrs_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/ThreeDotsLabs/watermill" - "github.com/ThreeDotsLabs/watermill/components/cqrs" -) - -func TestStructNameMarshaler(t *testing.T) { - eventToMarshal := TestEvent{ - ID: watermill.NewULID(), - When: time.Date(2016, time.August, 15, 14, 13, 12, 0, time.UTC), - } - - marshaler := &cqrs.StructNameMarshaler{} - - msg, err := marshaler.Marshal(eventToMarshal) - require.NoError(t, err) - - assert.Equal(t, "TestEvent", marshaler.NameFromMessage(msg)) - - eventToUnmarshal := TestEvent{} - err = marshaler.Unmarshal(msg, &eventToUnmarshal) - require.NoError(t, err) - - assert.EqualValues(t, eventToMarshal, eventToUnmarshal) - assert.Equal(t, "TestEvent", marshaler.Name(eventToUnmarshal)) -} From 8400f41d0f87fec7f5a5d70e1bfcb4c666f76971 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Thu, 23 May 2019 11:44:19 +0200 Subject: [PATCH 5/6] Add fallback to message name generator --- components/cqrs/name.go | 18 ++++++++++-------- components/cqrs/name_test.go | 10 ++++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/components/cqrs/name.go b/components/cqrs/name.go index 78fe03619..6b4f06993 100644 --- a/components/cqrs/name.go +++ b/components/cqrs/name.go @@ -27,14 +27,16 @@ type namedMessage interface { } // MessageName returns the name from a message implementing the following interface: -// type namedMessage interface { -// Name() string -// } +// type namedMessage interface { +// Name() string +// } // It ignores if the value is a pointer or not. -func MessageName(v interface{}) string { - if v, ok := v.(namedMessage); ok { - return v.Name() - } +func MessageName(fallback func(v interface{}) string) func(v interface{}) string { + return func(v interface{}) string { + if v, ok := v.(namedMessage); ok { + return v.Name() + } - return "" + return fallback(v) + } } diff --git a/components/cqrs/name_test.go b/components/cqrs/name_test.go index 5080778a0..1310770aa 100644 --- a/components/cqrs/name_test.go +++ b/components/cqrs/name_test.go @@ -32,8 +32,14 @@ func TestStructName(t *testing.T) { } func TestMessageName(t *testing.T) { - assert.Equal(t, "named object", cqrs.MessageName(namedObject{})) - assert.Equal(t, "named object", cqrs.MessageName(&namedObject{})) + 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{} From c420641a720f3b57882b93265ef8680fcee7f1ea Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Fri, 24 May 2019 22:08:52 +0200 Subject: [PATCH 6/6] Improve name generator names --- components/cqrs/marshaler_json.go | 2 +- components/cqrs/marshaler_protobuf.go | 2 +- components/cqrs/name.go | 14 +++++++------- components/cqrs/name_test.go | 20 ++++++++++---------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/components/cqrs/marshaler_json.go b/components/cqrs/marshaler_json.go index a2fd00337..09c2b7cc1 100644 --- a/components/cqrs/marshaler_json.go +++ b/components/cqrs/marshaler_json.go @@ -45,7 +45,7 @@ func (m JSONMarshaler) Name(cmdOrEvent interface{}) string { return m.GenerateName(cmdOrEvent) } - return ObjectName(cmdOrEvent) + return FullyQualifiedStructName(cmdOrEvent) } func (m JSONMarshaler) NameFromMessage(msg *message.Message) string { diff --git a/components/cqrs/marshaler_protobuf.go b/components/cqrs/marshaler_protobuf.go index 45cb9eb69..3dff6308a 100644 --- a/components/cqrs/marshaler_protobuf.go +++ b/components/cqrs/marshaler_protobuf.go @@ -66,7 +66,7 @@ func (m ProtobufMarshaler) Name(cmdOrEvent interface{}) string { return m.GenerateName(cmdOrEvent) } - return ObjectName(cmdOrEvent) + return FullyQualifiedStructName(cmdOrEvent) } func (m ProtobufMarshaler) NameFromMessage(msg *message.Message) string { diff --git a/components/cqrs/name.go b/components/cqrs/name.go index 6b4f06993..463b9d77f 100644 --- a/components/cqrs/name.go +++ b/components/cqrs/name.go @@ -5,9 +5,9 @@ import ( "strings" ) -// ObjectName name returns object name in format [package].[type name]. +// FullyQualifiedStructName name returns object name in format [package].[type name]. // It ignores if the value is a pointer or not. -func ObjectName(v interface{}) string { +func FullyQualifiedStructName(v interface{}) string { s := fmt.Sprintf("%T", v) s = strings.TrimLeft(s, "*") @@ -22,18 +22,18 @@ func StructName(v interface{}) string { return segments[len(segments)-1] } -type namedMessage interface { +type namedStruct interface { Name() string } -// MessageName returns the name from a message implementing the following interface: -// type namedMessage interface { +// NamedStruct returns the name from a message implementing the following interface: +// type namedStruct interface { // Name() string // } // It ignores if the value is a pointer or not. -func MessageName(fallback func(v interface{}) string) func(v interface{}) string { +func NamedStruct(fallback func(v interface{}) string) func(v interface{}) string { return func(v interface{}) string { - if v, ok := v.(namedMessage); ok { + if v, ok := v.(namedStruct); ok { return v.Name() } diff --git a/components/cqrs/name_test.go b/components/cqrs/name_test.go index 1310770aa..49e578560 100644 --- a/components/cqrs/name_test.go +++ b/components/cqrs/name_test.go @@ -8,19 +8,19 @@ import ( "github.com/ThreeDotsLabs/watermill/components/cqrs" ) -func TestObjectName(t *testing.T) { +func TestFullyQualifiedStructName(t *testing.T) { type Object struct{} - assert.Equal(t, "cqrs_test.Object", cqrs.ObjectName(Object{})) - assert.Equal(t, "cqrs_test.Object", cqrs.ObjectName(&Object{})) + assert.Equal(t, "cqrs_test.Object", cqrs.FullyQualifiedStructName(Object{})) + assert.Equal(t, "cqrs_test.Object", cqrs.FullyQualifiedStructName(&Object{})) } -func BenchmarkObjectName(b *testing.B) { +func BenchmarkFullyQualifiedStructName(b *testing.B) { type Object struct{} o := Object{} for i := 0; i < b.N; i++ { - cqrs.ObjectName(o) + cqrs.FullyQualifiedStructName(o) } } @@ -31,15 +31,15 @@ func TestStructName(t *testing.T) { 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{})) +func TestNamedStruct(t *testing.T) { + assert.Equal(t, "named object", cqrs.NamedStruct(cqrs.StructName)(namedObject{})) + assert.Equal(t, "named object", cqrs.NamedStruct(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{})) + assert.Equal(t, "Object", cqrs.NamedStruct(cqrs.StructName)(Object{})) + assert.Equal(t, "Object", cqrs.NamedStruct(cqrs.StructName)(&Object{})) } type namedObject struct{}