diff --git a/field/binary.go b/field/binary.go index d1813c5..07a4870 100644 --- a/field/binary.go +++ b/field/binary.go @@ -1,9 +1,10 @@ package field import ( + "encoding/hex" "encoding/json" - "errors" "fmt" + "reflect" "github.com/moov-io/iso8583/encoding" "github.com/moov-io/iso8583/utils" @@ -16,7 +17,6 @@ var _ json.Unmarshaler = (*Binary)(nil) type Binary struct { value []byte spec *Spec - data *Binary } func NewBinary(spec *Spec) *Binary { @@ -41,9 +41,6 @@ func (f *Binary) SetSpec(spec *Spec) { func (f *Binary) SetBytes(b []byte) error { f.value = b - if f.data != nil { - *(f.data) = *f - } return nil } @@ -120,34 +117,64 @@ func (f *Binary) SetData(data interface{}) error { } func (f *Binary) Unmarshal(v interface{}) error { - if v == nil { - return nil - } - - bin, ok := v.(*Binary) - if !ok { - return errors.New("data does not match required *Binary type") + switch val := v.(type) { + case reflect.Value: + if !val.CanSet() { + return fmt.Errorf("cannot set reflect.Value of type %s", val.Kind()) + } + + switch val.Kind() { //nolint:exhaustive + case reflect.String: + val.SetString(hex.EncodeToString(f.value)) + case reflect.Slice: + val.SetBytes(f.value) + default: + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) + } + case *string: + *val = hex.EncodeToString(f.value) + case *[]byte: + *val = f.value + case *Binary: + val.value = f.value + default: + return fmt.Errorf("unsupported type: expected *Binary, *string, *[]byte, or reflect.Value, got %T", v) } - bin.value = f.value - return nil } func (f *Binary) Marshal(v interface{}) error { - if v == nil { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = nil return nil } - bin, ok := v.(*Binary) - if !ok { - return errors.New("data does not match required *Binary type") - } + switch v := v.(type) { + case *Binary: + f.value = v.value + case string: + buf, err := hex.DecodeString(v) + if err != nil { + return fmt.Errorf("failed to convert string to byte: %w", err) + } - f.data = bin - if bin.value != nil { - f.value = bin.value + f.value = buf + case *string: + buf, err := hex.DecodeString(*v) + if err != nil { + return fmt.Errorf("failed to convert string to byte: %w", err) + } + + f.value = buf + case []byte: + f.SetBytes(v) + case *[]byte: + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Binary or (string, *string, []byte, *[]byte) type") } + return nil } diff --git a/field/binary_test.go b/field/binary_test.go index e3670ed..227de55 100644 --- a/field/binary_test.go +++ b/field/binary_test.go @@ -1,6 +1,7 @@ package field import ( + "reflect" "testing" "github.com/moov-io/iso8583/encoding" @@ -76,7 +77,7 @@ func TestBinaryField(t *testing.T) { err := bin.SetBytes(in) require.NoError(t, err) - require.Equal(t, in, data.value) + require.Equal(t, in, bin.value) }) // SetValue sets data to the data field @@ -96,7 +97,7 @@ func TestBinaryField(t *testing.T) { require.NoError(t, err) require.Equal(t, len(in), n) - require.Equal(t, in, data.value) + require.Equal(t, in, bin.value) }) t.Run("UnmarshalJSON unquotes input before handling it", func(t *testing.T) { @@ -140,3 +141,76 @@ func TestBinaryNil(t *testing.T) { bs = str.Value() require.Nil(t, bs) } + +func TestBinaryFieldUnmarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + binaryField := NewBinaryValue(testValue) + + vBinary := &Binary{} + err := binaryField.Unmarshal(vBinary) + require.NoError(t, err) + require.Equal(t, testValue, vBinary.Value()) + + var s string + err = binaryField.Unmarshal(&s) + require.NoError(t, err) + require.Equal(t, "123456", s) + + var b []byte + err = binaryField.Unmarshal(&b) + require.NoError(t, err) + require.Equal(t, testValue, b) + + refStrValue := reflect.ValueOf(&s).Elem() + err = binaryField.Unmarshal(refStrValue) + require.NoError(t, err) + require.Equal(t, "123456", refStrValue.String()) + + refBytesValue := reflect.ValueOf(&b).Elem() + err = binaryField.Unmarshal(refBytesValue) + require.NoError(t, err) + require.Equal(t, testValue, refBytesValue.Bytes()) + + refStr := reflect.ValueOf(s) + err = binaryField.Unmarshal(refStr) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) + + refStrPointer := reflect.ValueOf(&s) + err = binaryField.Unmarshal(refStrPointer) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) + + err = binaryField.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "unsupported type: expected *Binary, *string, *[]byte, or reflect.Value, got ", err.Error()) +} + +func TestBinaryFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + binaryField := NewBinaryValue(nil) + + inputStr := "123456" + err := binaryField.Marshal(inputStr) + require.NoError(t, err) + require.Equal(t, testValue, binaryField.Value()) + + err = binaryField.Marshal(&inputStr) + require.NoError(t, err) + require.Equal(t, testValue, binaryField.Value()) + + err = binaryField.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, testValue, binaryField.Value()) + + err = binaryField.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, testValue, binaryField.Value()) + + err = binaryField.Marshal(nil) + require.NoError(t, err) + + err = binaryField.Marshal(123456) + require.Error(t, err) + require.Equal(t, "data does not match required *Binary or (string, *string, []byte, *[]byte) type", err.Error()) +} diff --git a/field/bitmap.go b/field/bitmap.go index a8f0e17..d7f64ac 100644 --- a/field/bitmap.go +++ b/field/bitmap.go @@ -126,7 +126,7 @@ func (f *Bitmap) Unmarshal(v interface{}) error { bmap, ok := v.(*Bitmap) if !ok { - return fmt.Errorf("data does not match required *Bitmap type") + return fmt.Errorf("unsupported type: expected *Bitmap, got %T", v) } bmap.data = f.data diff --git a/field/composite_test.go b/field/composite_test.go index 7993927..1e8f889 100644 --- a/field/composite_test.go +++ b/field/composite_test.go @@ -597,7 +597,7 @@ func TestCompositePacking(t *testing.T) { }) require.Error(t, err) - require.EqualError(t, err, "failed to set data from field 1: data does not match required *String type") + require.EqualError(t, err, "failed to set data from field 1: data does not match required *String or (string, *string, int, *int) type") }) t.Run("Pack returns error on failure of subfield packing", func(t *testing.T) { @@ -747,7 +747,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.EqualError(t, err, "failed to get data from field 1: unsupported type: expected *String, *string, or reflect.Value, got *field.Numeric") }) t.Run("Unpack returns an error on failure of subfield to unpack bytes", func(t *testing.T) { diff --git a/field/hex.go b/field/hex.go index 36d8b0f..e9b15fb 100644 --- a/field/hex.go +++ b/field/hex.go @@ -3,8 +3,8 @@ package field import ( "encoding/hex" "encoding/json" - "errors" "fmt" + "reflect" "strings" "github.com/moov-io/iso8583/utils" @@ -22,7 +22,6 @@ var _ json.Unmarshaler = (*Hex)(nil) type Hex struct { value string spec *Spec - data *Hex } func NewHex(spec *Spec) *Hex { @@ -50,9 +49,6 @@ func (f *Hex) SetSpec(spec *Spec) { func (f *Hex) SetBytes(b []byte) error { f.value = strings.ToUpper(hex.EncodeToString(b)) - if f.data != nil { - *(f.data) = *f - } return nil } @@ -132,34 +128,56 @@ func (f *Hex) SetData(data interface{}) error { } func (f *Hex) Unmarshal(v interface{}) error { - if v == nil { - return nil - } - - str, ok := v.(*Hex) - if !ok { - return errors.New("data does not match required *Hex type") + switch val := v.(type) { + case reflect.Value: + if !val.CanSet() { + return fmt.Errorf("cannot set reflect.Value of type %s", val.Kind()) + } + + switch val.Kind() { //nolint:exhaustive + case reflect.String: + str, _ := f.String() + val.SetString(str) + case reflect.Slice: + buf, _ := f.Bytes() + val.SetBytes(buf) + default: + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) + } + case *string: + *val, _ = f.String() + case *[]byte: + *val, _ = f.Bytes() + case *Hex: + val.value = f.value + default: + return fmt.Errorf("unsupported type: expected *Hex, *string, *[]byte, or reflect.Value, got %T", v) } - str.value = f.value - return nil } func (f *Hex) Marshal(v interface{}) error { - if v == nil { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = "" return nil } - str, ok := v.(*Hex) - if !ok { - return fmt.Errorf("data does not match required *Hex type") + switch v := v.(type) { + case *Hex: + f.value = v.value + case string: + f.value = v + case *string: + f.value = *v + case []byte: + f.SetBytes(v) + case *[]byte: + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Hex or (string, *string, []byte, *[]byte) type") } - f.data = str - if str.value != "" { - f.value = str.value - } return nil } diff --git a/field/hex_test.go b/field/hex_test.go index 25c4a96..3b0edcb 100644 --- a/field/hex_test.go +++ b/field/hex_test.go @@ -2,6 +2,7 @@ package field import ( "errors" + "reflect" "testing" "github.com/moov-io/iso8583/encoding" @@ -142,3 +143,86 @@ func TestHexPack(t *testing.T) { require.EqualError(t, err, "failed to encode length: field length: 0 should be fixed: 10") }) } + +func TestHexFieldUnmarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + hexField := NewHexValue("123456") + + vHex := &Hex{} + err := hexField.Unmarshal(vHex) + require.NoError(t, err) + require.Equal(t, "123456", vHex.Value()) + buf, _ := vHex.Bytes() + require.Equal(t, testValue, buf) + + var s string + err = hexField.Unmarshal(&s) + require.NoError(t, err) + require.Equal(t, "123456", s) + + var b []byte + err = hexField.Unmarshal(&b) + require.NoError(t, err) + require.Equal(t, testValue, b) + + refStrValue := reflect.ValueOf(&s).Elem() + err = hexField.Unmarshal(refStrValue) + require.NoError(t, err) + require.Equal(t, "123456", refStrValue.String()) + + refBytesValue := reflect.ValueOf(&b).Elem() + err = hexField.Unmarshal(refBytesValue) + require.NoError(t, err) + require.Equal(t, testValue, refBytesValue.Bytes()) + + refStr := reflect.ValueOf(s) + err = hexField.Unmarshal(refStr) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) + + refStrPointer := reflect.ValueOf(&s) + err = hexField.Unmarshal(refStrPointer) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) + + err = hexField.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "unsupported type: expected *Hex, *string, *[]byte, or reflect.Value, got ", err.Error()) +} + +func TestHexFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + hexField := NewHexValue("") + + inputStr := "123456" + err := hexField.Marshal(inputStr) + require.NoError(t, err) + require.Equal(t, "123456", hexField.Value()) + buf, _ := hexField.Bytes() + require.Equal(t, testValue, buf) + + err = hexField.Marshal(&inputStr) + require.NoError(t, err) + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() + require.Equal(t, testValue, buf) + + err = hexField.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() + require.Equal(t, testValue, buf) + + err = hexField.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() + require.Equal(t, testValue, buf) + + err = hexField.Marshal(nil) + require.NoError(t, err) + + err = hexField.Marshal(123456) + require.Error(t, err) + require.Equal(t, "data does not match required *Hex or (string, *string, []byte, *[]byte) type", err.Error()) +} diff --git a/field/numeric.go b/field/numeric.go index 7c17f1b..d3e5e7d 100644 --- a/field/numeric.go +++ b/field/numeric.go @@ -2,8 +2,8 @@ package field import ( "encoding/json" - "errors" "fmt" + "reflect" "strconv" "github.com/moov-io/iso8583/utils" @@ -16,7 +16,6 @@ var _ json.Unmarshaler = (*Numeric)(nil) type Numeric struct { value int spec *Spec - data *Numeric } func NewNumeric(spec *Spec) *Numeric { @@ -54,9 +53,6 @@ func (f *Numeric) SetBytes(b []byte) error { f.value = val } - if f.data != nil { - *(f.data) = *f - } return nil } @@ -134,33 +130,64 @@ func (f *Numeric) SetData(data interface{}) error { } func (f *Numeric) Unmarshal(v interface{}) error { - if v == nil { - return nil - } - num, ok := v.(*Numeric) - if !ok { - return errors.New("data does not match required *Numeric type") - } + switch val := v.(type) { + case reflect.Value: + if !val.CanSet() { + return fmt.Errorf("cannot set reflect.Value of type %s", val.Kind()) + } - num.value = f.value + switch val.Kind() { //nolint:exhaustive + case reflect.String: + str := strconv.Itoa(f.value) + val.SetString(str) + case reflect.Int: + val.SetInt(int64(f.value)) + default: + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) + } + case *string: + str := strconv.Itoa(f.value) + *val = str + case *int: + *val = f.value + case *Numeric: + val.value = f.value + default: + return fmt.Errorf("unsupported type: expected *Numeric, *int, or reflect.Value, got %T", v) + } return nil } func (f *Numeric) Marshal(v interface{}) error { - if v == nil { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = 0 return nil } - num, ok := v.(*Numeric) - if !ok { - return fmt.Errorf("data does not match required *Numeric type") + switch v := v.(type) { + case *Numeric: + f.value = v.value + case int: + f.value = v + case *int: + f.value = *v + case string: + val, err := strconv.Atoi(v) + if err != nil { + return utils.NewSafeError(err, "failed to convert sting value into number") + } + f.value = val + case *string: + val, err := strconv.Atoi(*v) + if err != nil { + return utils.NewSafeError(err, "failed to convert sting value into number") + } + f.value = val + default: + return fmt.Errorf("data does not match require *Numeric or (int, *int, string, *string) type") } - f.data = num - if num.value != 0 { - f.value = num.value - } return nil } diff --git a/field/numeric_test.go b/field/numeric_test.go index 1da167e..4845013 100644 --- a/field/numeric_test.go +++ b/field/numeric_test.go @@ -1,6 +1,7 @@ package field import ( + "reflect" "testing" "github.com/moov-io/iso8583/encoding" @@ -48,7 +49,7 @@ func TestNumericField(t *testing.T) { length, err = numeric.Unpack([]byte(" 9876")) require.NoError(t, err) require.Equal(t, 10, length) - require.Equal(t, 9876, data.Value()) + require.Equal(t, 9876, numeric.Value()) numeric = NewNumeric(spec) numeric.SetValue(9876) @@ -88,14 +89,78 @@ func TestNumericPack(t *testing.T) { } func TestNumericFieldUnmarshal(t *testing.T) { - str := NewNumericValue(9876) + numericField := NewNumericValue(123456) + + vNumeric := &Numeric{} + err := numericField.Unmarshal(vNumeric) + require.NoError(t, err) + require.Equal(t, 123456, vNumeric.Value()) - val := &Numeric{} + var s string + err = numericField.Unmarshal(&s) + require.NoError(t, err) + require.Equal(t, "123456", s) - err := str.Unmarshal(val) + var b int + err = numericField.Unmarshal(&b) + require.NoError(t, err) + require.Equal(t, 123456, b) + + refStrValue := reflect.ValueOf(&s).Elem() + err = numericField.Unmarshal(refStrValue) + require.NoError(t, err) + require.Equal(t, "123456", refStrValue.String()) + refIntValue := reflect.ValueOf(&b).Elem() + err = numericField.Unmarshal(refIntValue) require.NoError(t, err) - require.Equal(t, 9876, val.Value()) + require.Equal(t, 123456, int(refIntValue.Int())) + + refStr := reflect.ValueOf(s) + err = numericField.Unmarshal(refStr) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) + + refStrPointer := reflect.ValueOf(&s) + err = numericField.Unmarshal(refStrPointer) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) + + err = numericField.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "unsupported type: expected *Numeric, *int, or reflect.Value, got ", err.Error()) +} + +func TestNumericFieldMarshal(t *testing.T) { + numericField := NewNumericValue(0) + + inputNumeric := NewNumericValue(123456) + numericField.Marshal(inputNumeric) + require.Equal(t, 123456, numericField.Value()) + + numericField.Marshal(&inputNumeric) + require.Equal(t, 123456, numericField.Value()) + + inputStr := "123456" + numericField.Marshal(inputStr) + require.Equal(t, 123456, numericField.Value()) + + numericField.Marshal(&inputStr) + require.Equal(t, 123456, numericField.Value()) + + inputInt := 123456 + numericField.Marshal(inputInt) + require.Equal(t, 123456, numericField.Value()) + + numericField.Marshal(&inputInt) + require.Equal(t, 123456, numericField.Value()) + + err := numericField.Marshal(nil) + require.NoError(t, err) + + err = numericField.Marshal([]byte("123456")) + require.Error(t, err) + require.Equal(t, "data does not match require *Numeric or (int, *int, string, *string) type", err.Error()) } func TestNumericFieldWithNotANumber(t *testing.T) { @@ -165,7 +230,7 @@ func TestNumericSetBytesSetsDataOntoDataStruct(t *testing.T) { err = numeric.SetBytes([]byte("9")) require.NoError(t, err) - require.Equal(t, 9, data.Value()) + require.Equal(t, 9, numeric.Value()) } func TestNumericJSONMarshal(t *testing.T) { diff --git a/field/string.go b/field/string.go index 11421e2..2e88199 100644 --- a/field/string.go +++ b/field/string.go @@ -2,8 +2,9 @@ package field import ( "encoding/json" - "errors" "fmt" + "reflect" + "strconv" "github.com/moov-io/iso8583/utils" ) @@ -15,7 +16,6 @@ var _ json.Unmarshaler = (*String)(nil) type String struct { value string spec *Spec - data *String } func NewString(spec *Spec) *String { @@ -40,9 +40,6 @@ func (f *String) SetSpec(spec *Spec) { func (f *String) SetBytes(b []byte) error { f.value = string(b) - if f.data != nil { - *(f.data) = *f - } return nil } @@ -119,34 +116,63 @@ func (f *String) SetData(data interface{}) 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: + if !val.CanSet() { + return fmt.Errorf("cannot set reflect.Value of type %s", val.Kind()) + } + + switch val.Kind() { //nolint:exhaustive + 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("unsupported reflect.Value type: %s", val.Kind()) + } + 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("unsupported type: expected *String, *string, or reflect.Value, got %T", v) } - str.value = f.value - return nil } func (f *String) Marshal(v interface{}) error { - if v == nil { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = "" return nil } - str, ok := v.(*String) - if !ok { - return fmt.Errorf("data does not match required *String type") + switch v := v.(type) { + case *String: + f.value = v.value + case string: + f.value = v + case *string: + f.value = *v + case int: + f.value = strconv.FormatInt(int64(v), 10) + case *int: + f.value = strconv.FormatInt(int64(*v), 10) + default: + return fmt.Errorf("data does not match required *String or (string, *string, int, *int) type") } - f.data = str - if str.value != "" { - f.value = str.value - } return nil } diff --git a/field/string_test.go b/field/string_test.go index 2158d3f..01d1b09 100644 --- a/field/string_test.go +++ b/field/string_test.go @@ -1,6 +1,7 @@ package field import ( + "reflect" "testing" "github.com/moov-io/iso8583/encoding" @@ -43,24 +44,19 @@ func TestStringField(t *testing.T) { require.Equal(t, " hello", string(packed)) str = NewString(spec) - data := NewStringValue("") - str.Marshal(data) length, err = str.Unpack([]byte(" olleh")) require.NoError(t, err) require.Equal(t, 10, length) - require.Equal(t, "olleh", data.Value()) + require.Equal(t, "olleh", str.Value()) str = NewString(spec) - data = &String{} - str.Marshal(data) err = str.SetBytes([]byte("hello")) require.NoError(t, err) - require.Equal(t, "hello", data.Value()) + require.Equal(t, "hello", str.Value()) str = NewString(spec) - str.SetValue("hello") - require.Equal(t, "hello", data.Value()) + require.Equal(t, "hello", str.Value()) } func TestStringNil(t *testing.T) { @@ -94,14 +90,78 @@ func TestStringPack(t *testing.T) { } func TestStringFieldUnmarshal(t *testing.T) { - str := NewStringValue("hello") + stringField := NewStringValue("123456") + + vString := &String{} + err := stringField.Unmarshal(vString) + require.NoError(t, err) + require.Equal(t, "123456", vString.Value()) + + var s string + err = stringField.Unmarshal(&s) + require.NoError(t, err) + require.Equal(t, "123456", s) + + var b int + err = stringField.Unmarshal(&b) + require.NoError(t, err) + require.Equal(t, 123456, b) + + refStrValue := reflect.ValueOf(&s).Elem() + err = stringField.Unmarshal(refStrValue) + require.NoError(t, err) + require.Equal(t, "123456", refStrValue.String()) - val := &String{} + refIntValue := reflect.ValueOf(&b).Elem() + err = stringField.Unmarshal(refIntValue) + require.NoError(t, err) + require.Equal(t, 123456, int(refIntValue.Int())) + + refStr := reflect.ValueOf(s) + err = stringField.Unmarshal(refStr) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) + + refStrPointer := reflect.ValueOf(&s) + err = stringField.Unmarshal(refStrPointer) + require.Error(t, err) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) + + err = stringField.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "unsupported type: expected *String, *string, or reflect.Value, got ", err.Error()) +} + +func TestStringFieldMarshal(t *testing.T) { + stringField := NewStringValue("") - err := str.Unmarshal(val) + inputString := NewStringValue("123456") + stringField.Marshal(inputString) + require.Equal(t, "123456", stringField.Value()) + stringField.Marshal(&inputString) + require.Equal(t, "123456", stringField.Value()) + + inputStr := "123456" + stringField.Marshal(inputStr) + require.Equal(t, "123456", stringField.Value()) + + stringField.Marshal(&inputStr) + require.Equal(t, "123456", stringField.Value()) + + inputInt := 123456 + stringField.Marshal(inputInt) + require.Equal(t, "123456", stringField.Value()) + + stringField.Marshal(&inputInt) + require.Equal(t, "123456", stringField.Value()) + + err := stringField.Marshal(nil) require.NoError(t, err) - require.Equal(t, "hello", val.Value()) + + err = stringField.Marshal([]byte("123456")) + require.Error(t, err) + require.Equal(t, "data does not match required *String or (string, *string, int, *int) type", err.Error()) } func TestStringJSONUnmarshal(t *testing.T) { diff --git a/field/track1.go b/field/track1.go index 519bd91..afc421d 100644 --- a/field/track1.go +++ b/field/track1.go @@ -123,7 +123,7 @@ func (f *Track1) Unmarshal(v interface{}) error { track, ok := v.(*Track1) if !ok { - return fmt.Errorf("data does not match required *Track1 type") + return fmt.Errorf("unsupported type: expected *Track1, got %T", v) } track.FixedLength = f.FixedLength @@ -144,7 +144,7 @@ func (f *Track1) Marshal(v interface{}) error { track, ok := v.(*Track1) if !ok { - return fmt.Errorf("data does not match required *Track type") + return fmt.Errorf("unsupported type: expected *Track1, got %T", v) } f.FixedLength = track.FixedLength diff --git a/field/track2.go b/field/track2.go index e94d6d2..ec4aea9 100644 --- a/field/track2.go +++ b/field/track2.go @@ -121,7 +121,7 @@ func (f *Track2) Unmarshal(v interface{}) error { track, ok := v.(*Track2) if !ok { - return fmt.Errorf("data does not match required *Track2 type") + return fmt.Errorf("unsupported type: expected *Track2, got %T", v) } track.PrimaryAccountNumber = f.PrimaryAccountNumber @@ -140,7 +140,7 @@ func (f *Track2) Marshal(v interface{}) error { track, ok := v.(*Track2) if !ok { - return fmt.Errorf("data does not match required *Track type") + return fmt.Errorf("unsupported type: expected *Track2, got %T", v) } f.PrimaryAccountNumber = track.PrimaryAccountNumber diff --git a/field/track3.go b/field/track3.go index 86ac72b..9739050 100644 --- a/field/track3.go +++ b/field/track3.go @@ -120,7 +120,7 @@ func (f *Track3) Unmarshal(v interface{}) error { track, ok := v.(*Track3) if !ok { - return fmt.Errorf("data does not match required *Track3 type") + return fmt.Errorf("unsupported type: expected *Track3, got %T", v) } track.PrimaryAccountNumber = f.PrimaryAccountNumber @@ -137,7 +137,7 @@ func (f *Track3) Marshal(v interface{}) error { track, ok := v.(*Track3) if !ok { - return fmt.Errorf("data does not match required *Track type") + return fmt.Errorf("unsupported type: expected *Track3, got %T", v) } f.FormatCode = track.FormatCode diff --git a/field/track_test.go b/field/track_test.go index f52e2ab..edab9e4 100644 --- a/field/track_test.go +++ b/field/track_test.go @@ -138,7 +138,7 @@ func TestTrack1(t *testing.T) { t.Run("Returns an error on mismatch of track type", func(t *testing.T) { track := NewTrack1(track1Spec) err := track.Marshal(NewStringValue("hello")) - require.EqualError(t, err, "data does not match required *Track type") + require.EqualError(t, err, "unsupported type: expected *Track1, got *field.String") }) t.Run("Unmarshal gets track values into data parameter", func(t *testing.T) { @@ -305,7 +305,7 @@ func TestTrack2TypedAPI(t *testing.T) { t.Run("Returns an error on mismatch of track type", func(t *testing.T) { track := NewTrack2(track2Spec) err := track.Marshal(NewStringValue("hello")) - require.EqualError(t, err, "data does not match required *Track type") + require.EqualError(t, err, "unsupported type: expected *Track2, got *field.String") }) t.Run("Unmarshal gets track values into data parameter", func(t *testing.T) { @@ -516,7 +516,7 @@ func TestTrack3TypedAPI(t *testing.T) { t.Run("Returns an error on mismatch of track type", func(t *testing.T) { track := NewTrack3(track3Spec) err := track.Marshal(NewStringValue("hello")) - require.EqualError(t, err, "data does not match required *Track type") + require.EqualError(t, err, "unsupported type: expected *Track3, got *field.String") }) t.Run("Unmarshal gets track values into data parameter", func(t *testing.T) {