Skip to content

Commit

Permalink
Merge pull request #231 from xmidt-org/more-is
Browse files Browse the repository at this point in the history
More is
  • Loading branch information
schmidtw authored Feb 27, 2025
2 parents 4b67e3e + 7a11f95 commit 67a657a
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
83 changes: 83 additions & 0 deletions example_extend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-FileCopyrightText: 2025 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package wrp_test

import (
"fmt"
"strings"

"github.com/xmidt-org/wrp-go/v5"
)

type Extended struct {
wrp.SimpleEvent
Extra string
}

var _ wrp.Union = (*Extended)(nil)

// Implement the wrp.Union interface for the Extended type.
func (e *Extended) MsgType() wrp.MessageType {
return wrp.SimpleEventMessageType
}

// Implement the wrp.Union interface for the Extended type.
func (e *Extended) To(msg *wrp.Message, v ...wrp.Processor) error {
e.SimpleEvent.Headers = []string{"extra: " + e.Extra}
return e.SimpleEvent.To(msg, v...)
}

// Implement the wrp.Union interface for the Extended type.
func (e *Extended) From(msg *wrp.Message, v ...wrp.Processor) error {
err := e.SimpleEvent.From(msg, v...)
if err != nil {
return err
}

e.Extra = ""
if len(e.SimpleEvent.Headers) > 0 {
after, found := strings.CutPrefix(e.SimpleEvent.Headers[0], "extra: ")
if found {
e.Extra = after
}
}

return nil
}

// Implement the wrp.Union interface for the Extended type.
func (e *Extended) Validate(v ...wrp.Processor) error {
return e.SimpleEvent.Validate(v...)
}

// Is reports whether the msg is the same type as the target, or is convertible
// to the target, without the need to validate the message. This function is not
// part of the wrp.Union interface, but it is a useful function to have when working
// with the wrp.Union interface.
func (e *Extended) Is(msg wrp.Union) bool {
var tmp wrp.SimpleEvent
if wrp.As(msg, &tmp, wrp.NoStandardValidation()) == nil {
if len(tmp.Headers) > 0 && strings.HasPrefix(tmp.Headers[0], "extra: ") {
return true
}
}

return false
}

func Example_extend() {
isExtended := wrp.SimpleEvent{
Headers: []string{"extra: something"},
}
isNotExtended := wrp.SimpleEvent{}

// The Extended type is a wrp.Union, so it can be used in the wrp.Is function.
// The wrp.Is function is useful for determining if the type matches, even if
// the message doesn't validate.
fmt.Printf("isExtended: %t\n", wrp.Is(&isExtended, &Extended{}))
fmt.Printf("isNotExtended: %t\n", wrp.Is(&isNotExtended, &Extended{}))

// Output: isExtended: true
// isNotExtended: false
}
12 changes: 12 additions & 0 deletions is.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ package wrp
// If the validators are not provided, the msg will be validated against the
// default validators. To skip validation, provide the NoStandardValidation()
// as a validator.
//
// If the target implements the Is(Union) bool method, that method will be
// called to determine if the msg is the same type as the target. If the target
// does not implement the Is(Union) method, the msg will be converted into a
// *Message and validated against the validators.
//
// Is() is valuable for determining if the type matches, even if the message
// doesn't validate.
func Is(msg, target Union, validators ...Processor) bool {
if msg == nil || target == nil {
return msg == nil && target == nil
Expand All @@ -21,6 +29,10 @@ func Is(msg, target Union, validators ...Processor) bool {
return false
}

if t, ok := target.(interface{ Is(Union) bool }); ok {
return t.Is(msg)
}

if m, ok := msg.(*Message); ok {
if err := m.Validate(validators...); err != nil {
return false
Expand Down
37 changes: 37 additions & 0 deletions is_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@ import (
"github.com/xmidt-org/wrp-go/v5"
)

// This type is here to show that a type that implements the wrp.Union interface
// can be used in the wrp.Is function. The Is() function is beyond the scope of
// of the wrp.Union interface, but it is a useful function to have when working
// with the wrp.Union interface as it allows the caller to determine if the
// message is of a specific type - even if it doesn't validate..
type isTest struct {
is bool
}

var _ wrp.Union = (*isTest)(nil)

func (i *isTest) MsgType() wrp.MessageType {
return wrp.UnknownMessageType
}

func (i *isTest) To(msg *wrp.Message, v ...wrp.Processor) error {
msg.Type = wrp.UnknownMessageType
return nil
}

func (i *isTest) From(msg *wrp.Message, v ...wrp.Processor) error {
return nil
}

func (i *isTest) Validate(v ...wrp.Processor) error {
return nil
}

func (i *isTest) Is(msg wrp.Union) bool {
return i.is
}

func TestIs(t *testing.T) {
tests := []struct {
desc string
Expand Down Expand Up @@ -68,6 +100,11 @@ func TestIs(t *testing.T) {
msg: &wrp.Unknown{},
target: &wrp.Message{Type: wrp.UnknownMessageType},
want: true,
}, {
desc: "msg type matches exact type",
msg: &wrp.Message{Type: wrp.UnknownMessageType},
target: &isTest{is: true},
want: true,
}, {
desc: "msg type is not the same type",
msg: &wrp.Message{Type: wrp.UnknownMessageType},
Expand Down

0 comments on commit 67a657a

Please sign in to comment.