Skip to content

Commit

Permalink
Update message.Marshal message to accept structs with go's native types
Browse files Browse the repository at this point in the history
  • Loading branch information
mfdeveloper508 authored and alovak committed Oct 5, 2023
1 parent ec6abff commit 0dc3f73
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 14 deletions.
24 changes: 17 additions & 7 deletions field/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,23 @@ func (f *Composite) Unmarshal(v interface{}) error {
}

dataField := dataStruct.Field(i)
if dataField.IsNil() {
dataField.Set(reflect.New(dataField.Type().Elem()))
}
switch dataField.Kind() { //nolint:exhaustive
case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
if dataField.IsNil() {
dataField.Set(reflect.New(dataField.Type().Elem()))
}

err = messageField.Unmarshal(dataField.Interface())
if err != nil {
return fmt.Errorf("failed to get data from field %s: %w", indexOrTag, err)
err = messageField.Unmarshal(dataField.Interface())
if err != nil {
return fmt.Errorf("failed to get data from field %s: %w", indexOrTag, err)
}
default: // Native types
vv := reflect.New(dataField.Type()).Elem()
err = messageField.Unmarshal(vv)
if err != nil {
return fmt.Errorf("failed to get data from field %s: %w", indexOrTag, err)
}
dataField.Set(vv)
}
}

Expand Down Expand Up @@ -259,7 +269,7 @@ func (f *Composite) Marshal(v interface{}) error {
}

dataField := dataStruct.Field(i)
if dataField.IsNil() {
if dataField.IsZero() {
continue
}

Expand Down
24 changes: 17 additions & 7 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ func (m *Message) Marshal(v interface{}) error {
}

dataField := dataStruct.Field(i)
if dataField.IsNil() {
if dataField.IsZero() {
continue
}

Expand Down Expand Up @@ -502,13 +502,23 @@ func (m *Message) Unmarshal(v interface{}) error {
}

dataField := dataStruct.Field(i)
if dataField.IsNil() {
dataField.Set(reflect.New(dataField.Type().Elem()))
}
switch dataField.Kind() { //nolint:exhaustive
case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
if dataField.IsNil() {
dataField.Set(reflect.New(dataField.Type().Elem()))
}

err = messageField.Unmarshal(dataField.Interface())
if err != nil {
return fmt.Errorf("failed to get value from field %d: %w", fieldIndex, err)
err = messageField.Unmarshal(dataField.Interface())
if err != nil {
return fmt.Errorf("failed to get value from field %d: %w", fieldIndex, err)
}
default: // Native types
vv := reflect.New(dataField.Type()).Elem()
err = messageField.Unmarshal(vv)
if err != nil {
return fmt.Errorf("failed to get value from field %d: %w", fieldIndex, err)
}
dataField.Set(vv)
}
}

Expand Down
82 changes: 82 additions & 0 deletions message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,53 @@ func TestMessage(t *testing.T) {
require.Equal(t, "100", data.F4.Value())
})

t.Run("Test unpacking message with untyped fields", func(t *testing.T) {
type TestISOF3Data struct {
F1 *string
F2 string
F3 string
}

type ISO87Data struct {
F0 *string
F2 string
F3 *TestISOF3Data
F4 string
}

message := NewMessage(spec)

rawMsg := []byte("01007000000000000000164242424242424242123456000000000100")
err := message.Unpack([]byte(rawMsg))

require.NoError(t, err)

s, err := message.GetString(2)
require.NoError(t, err)
require.Equal(t, "4242424242424242", s)

s, err = message.GetString(3)
require.NoError(t, err)
require.Equal(t, "123456", s)

s, err = message.GetString(4)
require.NoError(t, err)
require.Equal(t, "100", s)

data := &ISO87Data{}

require.NoError(t, message.Unmarshal(data))

require.NotNil(t, data.F0)
require.Equal(t, "0100", *data.F0)
require.Equal(t, "4242424242424242", data.F2)
require.NotNil(t, data.F3.F1)
require.Equal(t, "12", *data.F3.F1)
require.Equal(t, "34", data.F3.F2)
require.Equal(t, "56", data.F3.F3)
require.Equal(t, "100", data.F4)
})

t.Run("Test packing with typed fields", func(t *testing.T) {
type TestISOF3Data struct {
F1 *field.String
Expand Down Expand Up @@ -283,6 +330,41 @@ func TestMessage(t *testing.T) {
wantMsg := []byte("01007000000000000000164242424242424242123456000000000100")
require.Equal(t, wantMsg, rawMsg)
})

t.Run("Test packing message with untyped fields", func(t *testing.T) {
type TestISOF3Data struct {
F1 string
F2 string
F3 string
}

type ISO87Data struct {
F0 *string
F2 string
F3 *TestISOF3Data
F4 string
}

messageCode := "0100"
message := NewMessage(spec)
err := message.Marshal(&ISO87Data{
F0: &messageCode,
F2: "4242424242424242",
F3: &TestISOF3Data{
F1: "12",
F2: "34",
F3: "56",
},
F4: "100",
})
require.NoError(t, err)

rawMsg, err := message.Pack()
require.NoError(t, err)

wantMsg := []byte("01007000000000000000164242424242424242123456000000000100")
require.Equal(t, wantMsg, rawMsg)
})
}

func TestPackUnpack(t *testing.T) {
Expand Down

0 comments on commit 0dc3f73

Please sign in to comment.