Skip to content

Commit

Permalink
implement unmarshal
Browse files Browse the repository at this point in the history
  • Loading branch information
alovak committed Sep 11, 2023
1 parent 255001f commit 2f44c9f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 15 deletions.
39 changes: 39 additions & 0 deletions exp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/moov-io/iso8583"
"github.com/moov-io/iso8583/field"
"github.com/moov-io/iso8583/specs"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -164,4 +165,42 @@ func TestStructWithTypes(t *testing.T) {
})
}
})

t.Run("unpack", func(t *testing.T) {
type authRequest struct {
MTI string `index:"0"`
PrimaryAccountNumber string `index:"2"`
}

packed := []byte("011040000000000000000000000000000000164242424242424242")

message := iso8583.NewMessage(specs.Spec87ASCII)
err := message.Unpack(packed)
require.NoError(t, err)

data := authRequest{}
err = message.Unmarshal(&data)
require.NoError(t, err)
require.Equal(t, "0110", data.MTI)
require.Equal(t, "4242424242424242", data.PrimaryAccountNumber)
})

t.Run("unpack2", func(t *testing.T) {
type authRequest struct {
MTI *string `index:"0"`
PrimaryAccountNumber *field.String `index:"2"`
}

packed := []byte("011040000000000000000000000000000000164242424242424242")

message := iso8583.NewMessage(specs.Spec87ASCII)
err := message.Unpack(packed)
require.NoError(t, err)

data := authRequest{}
err = message.Unmarshal(&data)
require.NoError(t, err)
require.Equal(t, "0110", *data.MTI)
require.Equal(t, "4242424242424242", data.PrimaryAccountNumber.Value())
})
}
2 changes: 1 addition & 1 deletion field/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ func TestCompositePacking(t *testing.T) {
err = composite.Unmarshal(data)

require.Error(t, err)
require.EqualError(t, err, "failed to get data from field 1: data does not match required *String type")
require.Contains(t, err.Error(), "failed to get data from field 1: data does not match required *String")
})

t.Run("Unpack returns an error on failure of subfield to unpack bytes", func(t *testing.T) {
Expand Down
37 changes: 27 additions & 10 deletions field/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package field

import (
"encoding/json"
"errors"
"fmt"
"reflect"
"strconv"

"github.com/moov-io/iso8583/utils"
Expand Down Expand Up @@ -111,17 +111,34 @@ func (f *String) Unpack(data []byte) (int, error) {
}

func (f *String) Unmarshal(v interface{}) error {
if v == nil {
return nil
}

str, ok := v.(*String)
if !ok {
return errors.New("data does not match required *String type")
switch val := v.(type) {
case reflect.Value:
switch val.Kind() {
case reflect.String:
val.SetString(f.value)
case reflect.Int:
i, err := strconv.Atoi(f.value)
if err != nil {
return fmt.Errorf("failed to convert string to int: %w", err)
}
val.SetInt(int64(i))
default:
return fmt.Errorf("data does not match required reflect.Value type")
}
case *string:
*val = f.value
case *int:
i, err := strconv.Atoi(f.value)
if err != nil {
return fmt.Errorf("failed to convert string to int: %w", err)
}
*val = i
case *String:
val.value = f.value
default:
return fmt.Errorf("data does not match required *String or *string type")
}

str.value = f.value

return nil
}

Expand Down
16 changes: 12 additions & 4 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,11 +433,19 @@ func (m *Message) Unmarshal(v interface{}) error {
}

dataField := dataStruct.Field(i)
if dataField.IsNil() {
dataField.Set(reflect.New(dataField.Type().Elem()))
}

err = messageField.Unmarshal(dataField.Interface())
// if field is pointer we will pass pointer to the field
if dataField.Kind() == reflect.Ptr {
if dataField.IsZero() {
fmt.Println("is zero")

Check failure on line 440 in message.go

View workflow job for this annotation

GitHub Actions / Go Build (ubuntu-latest, stable)

use of `fmt.Println` forbidden by pattern `^fmt\.Print.*$` (forbidigo)

Check failure on line 440 in message.go

View workflow job for this annotation

GitHub Actions / Go Build (ubuntu-latest, oldstable)

use of `fmt.Println` forbidden by pattern `^fmt\.Print.*$` (forbidigo)
dataField.Set(reflect.New(dataField.Type().Elem()))
}

err = messageField.Unmarshal(dataField.Interface())
} else {
// if field is not pointer we will pass the field as reflect.Value
err = messageField.Unmarshal(dataField)
}
if err != nil {
return fmt.Errorf("failed to get value from field %d: %w", fieldIndex, err)
}
Expand Down

0 comments on commit 2f44c9f

Please sign in to comment.