From a4b1be2ea69aac2c6e2972080116786eb2911ca2 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:06:14 -0500 Subject: [PATCH 01/13] Deprecate SetData method --- field/binary.go | 15 +++++----- field/binary_test.go | 8 ++--- field/bitmap.go | 15 +++++----- field/bitmap_test.go | 10 +++---- field/composite_test.go | 66 ++++++++++++++++++++--------------------- field/hex.go | 15 +++++----- field/numeric.go | 15 +++++----- field/numeric_test.go | 6 ++-- field/string.go | 15 +++++----- field/string_test.go | 6 ++-- field/track1.go | 15 +++++----- field/track2.go | 15 +++++----- field/track3.go | 15 +++++----- field/track_test.go | 30 +++++++++---------- message_test.go | 10 +++---- 15 files changed, 132 insertions(+), 124 deletions(-) diff --git a/field/binary.go b/field/binary.go index 64d00a8c..d1813c51 100644 --- a/field/binary.go +++ b/field/binary.go @@ -114,6 +114,11 @@ func (f *Binary) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Binary) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Binary) Unmarshal(v interface{}) error { if v == nil { return nil @@ -129,12 +134,12 @@ func (f *Binary) Unmarshal(v interface{}) error { return nil } -func (f *Binary) SetData(data interface{}) error { - if data == nil { +func (f *Binary) Marshal(v interface{}) error { + if v == nil { return nil } - bin, ok := data.(*Binary) + bin, ok := v.(*Binary) if !ok { return errors.New("data does not match required *Binary type") } @@ -146,10 +151,6 @@ func (f *Binary) SetData(data interface{}) error { return nil } -func (f *Binary) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Binary) MarshalJSON() ([]byte, error) { str, err := f.String() if err != nil { diff --git a/field/binary_test.go b/field/binary_test.go index 903bfef5..e3670ed3 100644 --- a/field/binary_test.go +++ b/field/binary_test.go @@ -48,9 +48,9 @@ func TestBinaryField(t *testing.T) { require.Equal(t, in, bin.value) }) - t.Run("SetData sets data to the field", func(t *testing.T) { + t.Run("Marshal sets data to the field", func(t *testing.T) { bin := NewBinary(spec) - bin.SetData(NewBinaryValue(in)) + bin.Marshal(NewBinaryValue(in)) packed, err := bin.Pack() @@ -71,7 +71,7 @@ func TestBinaryField(t *testing.T) { t.Run("SetBytes sets data to the data field", func(t *testing.T) { bin := NewBinary(spec) data := &Binary{} - bin.SetData(data) + bin.Marshal(data) err := bin.SetBytes(in) require.NoError(t, err) @@ -90,7 +90,7 @@ func TestBinaryField(t *testing.T) { t.Run("Unpack sets data to data value", func(t *testing.T) { bin := NewBinary(spec) data := NewBinaryValue([]byte{}) - bin.SetData(data) + bin.Marshal(data) n, err := bin.Unpack(in) diff --git a/field/bitmap.go b/field/bitmap.go index db1b1ea6..a8f0e170 100644 --- a/field/bitmap.go +++ b/field/bitmap.go @@ -114,6 +114,11 @@ func (f *Bitmap) Unpack(data []byte) (int, error) { return read, nil } +// Deprecated. Use Marshal instead +func (f *Bitmap) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Bitmap) Unmarshal(v interface{}) error { if v == nil { return nil @@ -129,12 +134,12 @@ func (f *Bitmap) Unmarshal(v interface{}) error { return nil } -func (f *Bitmap) SetData(data interface{}) error { - if data == nil { +func (f *Bitmap) Marshal(v interface{}) error { + if v == nil { return nil } - bmap, ok := data.(*Bitmap) + bmap, ok := v.(*Bitmap) if !ok { return fmt.Errorf("data does not match required *Bitmap type") } @@ -143,10 +148,6 @@ func (f *Bitmap) SetData(data interface{}) error { return nil } -func (f *Bitmap) Marshal(data interface{}) error { - return f.SetData(data) -} - // Reset resets the bitmap to its initial state because of how message works, // Message need a way to initialize bitmap. That's why we set parameters to // their default values here like we do in constructor. diff --git a/field/bitmap_test.go b/field/bitmap_test.go index f203d43d..c8aa6d09 100644 --- a/field/bitmap_test.go +++ b/field/bitmap_test.go @@ -317,7 +317,7 @@ func TestBitmap_Unmarshal(t *testing.T) { }) } -func TestBitmap_SetData(t *testing.T) { +func TestBitmap_Marshal(t *testing.T) { spec := &Spec{ Description: "Bitmap", Enc: encoding.BytesToASCIIHex, @@ -327,7 +327,7 @@ func TestBitmap_SetData(t *testing.T) { t.Run("Nil data causes no side effects", func(t *testing.T) { bitmap := NewBitmap(spec) - err := bitmap.SetData(nil) + err := bitmap.Marshal(nil) require.NoError(t, err) require.Equal(t, NewBitmap(spec), bitmap) }) @@ -339,11 +339,11 @@ func TestBitmap_SetData(t *testing.T) { a string }{"left"} - err := bitmap.SetData(str) + err := bitmap.Marshal(str) require.Error(t, err) }) - t.Run("Unpack sets the data field with the correct bitmap provided using SetData", func(t *testing.T) { + t.Run("Unpack sets the data field with the correct bitmap provided using Marshal", func(t *testing.T) { bitmap := NewBitmap(spec) // set bit: 10 @@ -361,7 +361,7 @@ func TestBitmap_SetData(t *testing.T) { require.Equal(t, bitmapBytes, dataBytes) }) - t.Run("Pack returns bytes using the bitmap provided using SetData", func(t *testing.T) { + t.Run("Pack returns bytes using the bitmap provided using Marshal", func(t *testing.T) { bitmap := NewBitmap(spec) data := NewBitmap(&Spec{}) diff --git a/field/composite_test.go b/field/composite_test.go index 78d7fe08..79939278 100644 --- a/field/composite_test.go +++ b/field/composite_test.go @@ -349,10 +349,10 @@ type SubConstructedTLVTestData struct { F9F45 *Hex } -func TestComposite_SetData(t *testing.T) { - t.Run("SetData returns an error on provision of primitive type data", func(t *testing.T) { +func TestComposite_Marshal(t *testing.T) { + t.Run("Marshal returns an error on provision of primitive type data", func(t *testing.T) { composite := NewComposite(compositeTestSpec) - err := composite.SetData("primitive str") + err := composite.Marshal("primitive str") require.EqualError(t, err, "data is not a pointer or nil") }) } @@ -362,7 +362,7 @@ func TestCompositeFieldUnmarshal(t *testing.T) { // first, we need to populate fields of composite field // we will do it by packing the field composite := NewComposite(tlvTestSpec) - err := composite.SetData(&TLVTestData{ + err := composite.Marshal(&TLVTestData{ F9A: NewHexValue("210720"), F9F02: NewHexValue("000000000501"), }) @@ -381,7 +381,7 @@ func TestCompositeFieldUnmarshal(t *testing.T) { t.Run("Unmarshal gets data for composite field (constructed)", func(t *testing.T) { composite := NewComposite(constructedBERTLVTestSpec) - err := composite.SetData(&ConstructedTLVTestData{ + err := composite.Marshal(&ConstructedTLVTestData{ F82: NewHexValue("017F"), F9F36: NewHexValue("027F"), F9F3B: &SubConstructedTLVTestData{ @@ -410,7 +410,7 @@ func TestCompositeFieldUnmarshal(t *testing.T) { // first, we need to populate fields of composite field // we will do it by packing the field composite := NewComposite(tlvTestSpec) - err := composite.SetData(&TLVTestData{ + err := composite.Marshal(&TLVTestData{ F9A: NewHexValue("210720"), F9F02: NewHexValue("000000000501"), }) @@ -436,7 +436,7 @@ func TestTLVPacking(t *testing.T) { } composite := NewComposite(tlvTestSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -502,7 +502,7 @@ func TestTLVPacking(t *testing.T) { } composite := NewComposite(constructedBERTLVTestSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -592,7 +592,7 @@ func TestCompositePacking(t *testing.T) { F1 *Numeric } composite := NewComposite(compositeTestSpec) - err := composite.SetData(&TestDataIncorrectType{ + err := composite.Marshal(&TestDataIncorrectType{ F1: NewNumericValue(1), }) @@ -610,7 +610,7 @@ func TestCompositePacking(t *testing.T) { } composite := NewComposite(compositeTestSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) _, err = composite.Pack() @@ -666,7 +666,7 @@ func TestCompositePacking(t *testing.T) { } composite := NewComposite(compositeTestSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -754,7 +754,7 @@ func TestCompositePacking(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Last two characters must be an integer type. F3 fails to unpack. @@ -793,7 +793,7 @@ func TestCompositePacking(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(spec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Length of denoted by prefix is too long, causing failure to decode length. @@ -831,7 +831,7 @@ func TestCompositePacking(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(spec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // There is data only for first subfield @@ -947,7 +947,7 @@ func TestCompositePackingWithTags(t *testing.T) { } composite := NewComposite(invalidSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) b, err := composite.Pack() @@ -1010,7 +1010,7 @@ func TestCompositePackingWithTags(t *testing.T) { } composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1026,7 +1026,7 @@ func TestCompositePackingWithTags(t *testing.T) { } composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1043,7 +1043,7 @@ func TestCompositePackingWithTags(t *testing.T) { } composite := NewComposite(compositeTestSpecWithoutTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1056,7 +1056,7 @@ func TestCompositePackingWithTags(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // F3 fails to unpack - it requires len to be defined instead of AB. @@ -1070,7 +1070,7 @@ func TestCompositePackingWithTags(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Index 2-3 should have '01' rather than '12'. @@ -1083,7 +1083,7 @@ func TestCompositePackingWithTags(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Index 0, 1 should have '01' rather than 'ID'. @@ -1199,7 +1199,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { } composite := NewComposite(invalidSpec) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) b, err := composite.Pack() @@ -1262,7 +1262,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { } composite := NewComposite(compositeTestSpecWithDefaultBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1278,7 +1278,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { } composite := NewComposite(compositeTestSpecWithDefaultBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1299,7 +1299,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { } composite := NewComposite(compositeTestSpecWithSizedBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1315,7 +1315,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { } composite := NewComposite(compositeTestSpecWithSizedBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) packed, err := composite.Pack() @@ -1329,7 +1329,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithDefaultBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // F1 fails to unpack - it requires length to be defined instead of AB. @@ -1343,7 +1343,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithDefaultBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Index 2-3 = 70 indicates the presence of field 4. This field is not defined on spec. @@ -1408,7 +1408,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithSizedBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // F1 fails to unpack - it requires length to be defined instead of AB. @@ -1422,7 +1422,7 @@ func TestCompositePackingWithBitmap(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithSizedBitmap) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) // Index 2-3 = 70 indicates the presence of field 4. This field is not defined on spec. @@ -1722,7 +1722,7 @@ func TestCompositeJSONConversion(t *testing.T) { } composite := NewComposite(compositeTestSpecWithTagPadding) - require.NoError(t, composite.SetData(data)) + require.NoError(t, composite.Marshal(data)) actual, err := composite.MarshalJSON() require.NoError(t, err) @@ -1734,7 +1734,7 @@ func TestCompositeJSONConversion(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithTagPadding) - err := composite.SetData(data) + err := composite.Marshal(data) require.NoError(t, err) require.NoError(t, composite.UnmarshalJSON([]byte(json))) @@ -1761,7 +1761,7 @@ func TestCompositeJSONConversion(t *testing.T) { data := &CompositeTestData{} composite := NewComposite(compositeTestSpecWithTagPadding) - require.NoError(t, composite.SetData(data)) + require.NoError(t, composite.Marshal(data)) require.NoError(t, composite.UnmarshalJSON([]byte(json))) diff --git a/field/hex.go b/field/hex.go index d11f38e3..36d8b0f5 100644 --- a/field/hex.go +++ b/field/hex.go @@ -126,6 +126,11 @@ func (f *Hex) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Hex) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Hex) Unmarshal(v interface{}) error { if v == nil { return nil @@ -141,12 +146,12 @@ func (f *Hex) Unmarshal(v interface{}) error { return nil } -func (f *Hex) SetData(data interface{}) error { - if data == nil { +func (f *Hex) Marshal(v interface{}) error { + if v == nil { return nil } - str, ok := data.(*Hex) + str, ok := v.(*Hex) if !ok { return fmt.Errorf("data does not match required *Hex type") } @@ -158,10 +163,6 @@ func (f *Hex) SetData(data interface{}) error { return nil } -func (f *Hex) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Hex) MarshalJSON() ([]byte, error) { data, err := f.String() if err != nil { diff --git a/field/numeric.go b/field/numeric.go index 18e41936..7c17f1b1 100644 --- a/field/numeric.go +++ b/field/numeric.go @@ -128,6 +128,11 @@ func (f *Numeric) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Numeric) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Numeric) Unmarshal(v interface{}) error { if v == nil { return nil @@ -142,12 +147,12 @@ func (f *Numeric) Unmarshal(v interface{}) error { return nil } -func (f *Numeric) SetData(data interface{}) error { - if data == nil { +func (f *Numeric) Marshal(v interface{}) error { + if v == nil { return nil } - num, ok := data.(*Numeric) + num, ok := v.(*Numeric) if !ok { return fmt.Errorf("data does not match required *Numeric type") } @@ -159,10 +164,6 @@ func (f *Numeric) SetData(data interface{}) error { return nil } -func (f *Numeric) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Numeric) MarshalJSON() ([]byte, error) { bytes, err := json.Marshal(f.value) if err != nil { diff --git a/field/numeric_test.go b/field/numeric_test.go index c2ac8f87..1da167ea 100644 --- a/field/numeric_test.go +++ b/field/numeric_test.go @@ -37,14 +37,14 @@ func TestNumericField(t *testing.T) { require.Equal(t, 9876, numeric.Value()) numeric = NewNumeric(spec) - numeric.SetData(NewNumericValue(9876)) + numeric.Marshal(NewNumericValue(9876)) packed, err = numeric.Pack() require.NoError(t, err) require.Equal(t, " 9876", string(packed)) numeric = NewNumeric(spec) data := NewNumericValue(0) - numeric.SetData(data) + numeric.Marshal(data) length, err = numeric.Unpack([]byte(" 9876")) require.NoError(t, err) require.Equal(t, 10, length) @@ -159,7 +159,7 @@ func TestNumericSetBytesSetsDataOntoDataStruct(t *testing.T) { }) data := &Numeric{} - err := numeric.SetData(data) + err := numeric.Marshal(data) require.NoError(t, err) err = numeric.SetBytes([]byte("9")) diff --git a/field/string.go b/field/string.go index 94a1a8a4..11421e25 100644 --- a/field/string.go +++ b/field/string.go @@ -113,6 +113,11 @@ func (f *String) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *String) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *String) Unmarshal(v interface{}) error { if v == nil { return nil @@ -128,12 +133,12 @@ func (f *String) Unmarshal(v interface{}) error { return nil } -func (f *String) SetData(data interface{}) error { - if data == nil { +func (f *String) Marshal(v interface{}) error { + if v == nil { return nil } - str, ok := data.(*String) + str, ok := v.(*String) if !ok { return fmt.Errorf("data does not match required *String type") } @@ -145,10 +150,6 @@ func (f *String) SetData(data interface{}) error { return nil } -func (f *String) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *String) MarshalJSON() ([]byte, error) { bytes, err := json.Marshal(f.value) if err != nil { diff --git a/field/string_test.go b/field/string_test.go index f2537d32..2158d3ff 100644 --- a/field/string_test.go +++ b/field/string_test.go @@ -37,14 +37,14 @@ func TestStringField(t *testing.T) { require.Equal(t, "olleh", str.Value()) str = NewString(spec) - str.SetData(NewStringValue("hello")) + str.Marshal(NewStringValue("hello")) packed, err = str.Pack() require.NoError(t, err) require.Equal(t, " hello", string(packed)) str = NewString(spec) data := NewStringValue("") - str.SetData(data) + str.Marshal(data) length, err = str.Unpack([]byte(" olleh")) require.NoError(t, err) require.Equal(t, 10, length) @@ -52,7 +52,7 @@ func TestStringField(t *testing.T) { str = NewString(spec) data = &String{} - str.SetData(data) + str.Marshal(data) err = str.SetBytes([]byte("hello")) require.NoError(t, err) require.Equal(t, "hello", data.Value()) diff --git a/field/track1.go b/field/track1.go index f96aae9c..519bd914 100644 --- a/field/track1.go +++ b/field/track1.go @@ -111,6 +111,11 @@ func (f *Track1) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Track1) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Track1) Unmarshal(v interface{}) error { if v == nil { return nil @@ -132,12 +137,12 @@ func (f *Track1) Unmarshal(v interface{}) error { return nil } -func (f *Track1) SetData(data interface{}) error { - if data == nil { +func (f *Track1) Marshal(v interface{}) error { + if v == nil { return nil } - track, ok := data.(*Track1) + track, ok := v.(*Track1) if !ok { return fmt.Errorf("data does not match required *Track type") } @@ -155,10 +160,6 @@ func (f *Track1) SetData(data interface{}) error { return nil } -func (f *Track1) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Track1) unpack(raw []byte) error { if raw == nil || !track1Regex.Match(raw) { return errors.New("invalid track data") diff --git a/field/track2.go b/field/track2.go index 8d05383a..e94d6d26 100644 --- a/field/track2.go +++ b/field/track2.go @@ -109,6 +109,11 @@ func (f *Track2) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Track2) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Track2) Unmarshal(v interface{}) error { if v == nil { return nil @@ -128,12 +133,12 @@ func (f *Track2) Unmarshal(v interface{}) error { return nil } -func (f *Track2) SetData(data interface{}) error { - if data == nil { +func (f *Track2) Marshal(v interface{}) error { + if v == nil { return nil } - track, ok := data.(*Track2) + track, ok := v.(*Track2) if !ok { return fmt.Errorf("data does not match required *Track type") } @@ -149,10 +154,6 @@ func (f *Track2) SetData(data interface{}) error { return nil } -func (f *Track2) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Track2) unpack(raw []byte) error { if raw == nil || !track2Regex.Match(raw) { return errors.New("invalid track data") diff --git a/field/track3.go b/field/track3.go index 9e180b4a..86ac72b5 100644 --- a/field/track3.go +++ b/field/track3.go @@ -108,6 +108,11 @@ func (f *Track3) Unpack(data []byte) (int, error) { return read + prefBytes, nil } +// Deprecated. Use Marshal instead +func (f *Track3) SetData(data interface{}) error { + return f.Marshal(data) +} + func (f *Track3) Unmarshal(v interface{}) error { if v == nil { return nil @@ -125,12 +130,12 @@ func (f *Track3) Unmarshal(v interface{}) error { return nil } -func (f *Track3) SetData(data interface{}) error { - if data == nil { +func (f *Track3) Marshal(v interface{}) error { + if v == nil { return nil } - track, ok := data.(*Track3) + track, ok := v.(*Track3) if !ok { return fmt.Errorf("data does not match required *Track type") } @@ -144,10 +149,6 @@ func (f *Track3) SetData(data interface{}) error { return nil } -func (f *Track3) Marshal(data interface{}) error { - return f.SetData(data) -} - func (f *Track3) unpack(raw []byte) error { if raw == nil || !track3Regex.Match(raw) { return errors.New("invalid track data") diff --git a/field/track_test.go b/field/track_test.go index 7a71a4d2..f52e2ab7 100644 --- a/field/track_test.go +++ b/field/track_test.go @@ -137,7 +137,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.SetData(NewStringValue("hello")) + err := track.Marshal(NewStringValue("hello")) require.EqualError(t, err, "data does not match required *Track type") }) @@ -146,7 +146,7 @@ func TestTrack1(t *testing.T) { require.NoError(t, err) track := NewTrack1(track1Spec) - err = track.SetData(&Track1{ + err = track.Marshal(&Track1{ FixedLength: true, FormatCode: "B", PrimaryAccountNumber: "1234567890123445", @@ -185,7 +185,7 @@ func TestTrack1(t *testing.T) { } track := NewTrack1(track1Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) // test assigned fields @@ -208,7 +208,7 @@ func TestTrack1(t *testing.T) { data := &Track1{} track := NewTrack1(track1Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) _, err = track.Unpack(rawWithPrefix) @@ -230,7 +230,7 @@ func TestTrack1(t *testing.T) { data := &Track1{} track := NewTrack1(track1Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) err = track.SetBytes(raw) @@ -304,7 +304,7 @@ func TestTrack2TypedAPI(t *testing.T) { t.Run("Track 2 typed", func(t *testing.T) { t.Run("Returns an error on mismatch of track type", func(t *testing.T) { track := NewTrack2(track2Spec) - err := track.SetData(NewStringValue("hello")) + err := track.Marshal(NewStringValue("hello")) require.EqualError(t, err, "data does not match required *Track type") }) @@ -313,7 +313,7 @@ func TestTrack2TypedAPI(t *testing.T) { require.NoError(t, err) track := NewTrack2(track2Spec) - err = track.SetData(&Track2{ + err = track.Marshal(&Track2{ PrimaryAccountNumber: "4000340000000506", Separator: "D", ServiceCode: "111", @@ -366,7 +366,7 @@ func TestTrack2TypedAPI(t *testing.T) { } track := NewTrack2(track2Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) // test assigned fields @@ -404,7 +404,7 @@ func TestTrack2TypedAPI(t *testing.T) { data := &Track2{} track := NewTrack2(track2Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) _, err = track.Unpack(tc.Bytes) @@ -441,7 +441,7 @@ func TestTrack2TypedAPI(t *testing.T) { data := &Track2{} track := NewTrack2(track2Spec) - err = track.SetData(data) + err = track.Marshal(data) require.NoError(t, err) err = track.SetBytes(tc.TrackData) @@ -515,13 +515,13 @@ func TestTrack3TypedAPI(t *testing.T) { ) t.Run("Returns an error on mismatch of track type", func(t *testing.T) { track := NewTrack3(track3Spec) - err := track.SetData(NewStringValue("hello")) + err := track.Marshal(NewStringValue("hello")) require.EqualError(t, err, "data does not match required *Track type") }) t.Run("Unmarshal gets track values into data parameter", func(t *testing.T) { track := NewTrack3(track3Spec) - err := track.SetData(&Track3{ + err := track.Marshal(&Track3{ FormatCode: `01`, PrimaryAccountNumber: `1234567890123445`, DiscretionaryData: `724724000000000****00300XXXX020200099010=********************==1=100000000000000000**`, @@ -546,7 +546,7 @@ func TestTrack3TypedAPI(t *testing.T) { } track := NewTrack3(track3Spec) - err := track.SetData(data) + err := track.Marshal(data) require.NoError(t, err) // test assigned fields @@ -563,7 +563,7 @@ func TestTrack3TypedAPI(t *testing.T) { data := &Track3{} track := NewTrack3(track3Spec) - err := track.SetData(data) + err := track.Marshal(data) require.NoError(t, err) _, err = track.Unpack(rawWithPrefix) @@ -579,7 +579,7 @@ func TestTrack3TypedAPI(t *testing.T) { data := &Track3{} track := NewTrack3(track3Spec) - err := track.SetData(data) + err := track.Marshal(data) require.NoError(t, err) err = track.SetBytes(raw) diff --git a/message_test.go b/message_test.go index 7968340e..95f06348 100644 --- a/message_test.go +++ b/message_test.go @@ -265,7 +265,7 @@ func TestMessage(t *testing.T) { } message := NewMessage(spec) - err := message.SetData(&ISO87Data{ + err := message.Marshal(&ISO87Data{ F0: field.NewStringValue("0100"), F2: field.NewStringValue("4242424242424242"), F3: &TestISOF3Data{ @@ -535,7 +535,7 @@ func TestPackUnpack(t *testing.T) { t.Run("Pack data", func(t *testing.T) { message := NewMessage(spec) - err := message.SetData(&TestISOData{ + err := message.Marshal(&TestISOData{ F2: field.NewStringValue("4276555555555555"), F3: &TestISOF3Data{ F1: field.NewStringValue("00"), @@ -815,7 +815,7 @@ func TestMessageJSON(t *testing.T) { require.NoError(t, err) message := NewMessage(spec) - err = message.SetData(&TestISOData{ + err = message.Marshal(&TestISOData{ F0: field.NewStringValue("0100"), F2: field.NewStringValue("4242424242424242"), F3: &TestISOF3Data{ @@ -873,7 +873,7 @@ func TestMessageJSON(t *testing.T) { want := `{"0":"0100","1":"7000000000000000","2":"4242424242424242","3":{"1":"12","2":"34","3":"56"},"4":"100"}` message := NewMessage(spec) - message.SetData(&ISO87Data{}) + message.Marshal(&ISO87Data{}) rawMsg := []byte("01007000000000000000164242424242424242123456000000000100") require.NoError(t, message.Unpack([]byte(rawMsg))) @@ -1228,7 +1228,7 @@ func TestMessageClone(t *testing.T) { }, F120: field.NewStringValue("Another test text"), } - require.NoError(t, message.SetData(data2)) + require.NoError(t, message.Marshal(data2)) message.MTI("0100") From be33dcedce29cd48bf1a62f3c090f07f8b869821 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:11:29 -0500 Subject: [PATCH 02/13] fix wrong spelling --- field/field.go | 2 +- message.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/field/field.go b/field/field.go index 306153fd..234cee6e 100644 --- a/field/field.go +++ b/field/field.go @@ -23,7 +23,7 @@ type Field interface { // Bytes returns binary representation of the field Value Bytes() ([]byte, error) - // Deprecated. Use Marshal intead. + // Deprecated. Use Marshal instead. SetData(data interface{}) error // Unmarshal sets field Value into provided v. If v is nil or not diff --git a/message.go b/message.go index 01538508..54f01aae 100644 --- a/message.go +++ b/message.go @@ -51,7 +51,7 @@ func NewMessage(spec *MessageSpec) *Message { } } -// Deprecated. Use Marshal intead. +// Deprecated. Use Marshal instead. func (m *Message) SetData(data interface{}) error { return m.Marshal(data) } From dc7902ca8390c647226639187ad5a0ab9a25f546 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:24:20 -0500 Subject: [PATCH 03/13] Unpdate Unmarshal/Marshal method for the message and the rest of the fields --- field/binary.go | 95 +++++++++++++++++++++++++++++++------------ field/binary_test.go | 75 +++++++++++++++++++++++++++++++++- field/hex.go | 85 ++++++++++++++++++++++++++------------ field/hex_test.go | 81 ++++++++++++++++++++++++++++++++++++ field/numeric.go | 91 ++++++++++++++++++++++++++++++----------- field/numeric_test.go | 73 ++++++++++++++++++++++++++++++--- field/string.go | 87 +++++++++++++++++++++++++++------------ field/string_test.go | 80 ++++++++++++++++++++++++++++++------ 8 files changed, 548 insertions(+), 119 deletions(-) diff --git a/field/binary.go b/field/binary.go index d1813c51..7c9c3dfb 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,82 @@ func (f *Binary) SetData(data interface{}) error { } func (f *Binary) Unmarshal(v interface{}) error { - if v == nil { - return nil + switch val := v.(type) { + case reflect.Value: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str := hex.EncodeToString(f.value) + val.SetString(str) + case reflect.Slice: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetBytes(f.value) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + str := hex.EncodeToString(f.value) + *val = str + case *[]byte: + *val = f.value + case *Binary: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Binary or (*string, *[]byte) type") } - bin, ok := v.(*Binary) - if !ok { - return errors.New("data does not match required *Binary type") - } - - bin.value = f.value - return nil } func (f *Binary) Marshal(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 v := v.(type) { + case *Binary: + if v == nil { + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = nil + return nil + } + + buf, err := hex.DecodeString(v) + if err != nil { + return fmt.Errorf("failed to convert string to byte: %w", err) + } + + f.value = buf + case *string: + if v == nil { + f.value = nil + return nil + } + + 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: + if v == nil { + f.value = nil + return nil + } + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Binary or (string, *string, []byte, *[]byte) type") } - f.data = bin - if bin.value != nil { - f.value = bin.value - } return nil } diff --git a/field/binary_test.go b/field/binary_test.go index e3670ed3..6d300ba2 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,73 @@ func TestBinaryNil(t *testing.T) { bs = str.Value() require.Nil(t, bs) } + +func TestBinaryFieldUnmarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewBinaryValue(testValue) + + val1 := &Binary{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, testValue, val1.Value()) + + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + + var val3 []byte + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, testValue, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, testValue, val5.Bytes()) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Binary or (*string, *[]byte) type", err.Error()) +} + +func TestBinaryFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewBinaryValue(nil) + + vstring := "123456" + err := str.Marshal(vstring) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(&vstring) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(nil) + 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/hex.go b/field/hex.go index 36d8b0f5..8912be17 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,73 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str, _ := f.String() + val.SetString(str) + case reflect.Slice: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + buf, _ := f.Bytes() + val.SetBytes(buf) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + *val, _ = f.String() + case *[]byte: + *val, _ = f.Bytes() + case *Hex: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Hex or (*string, *[]byte) type") } - str.value = f.value - return nil } func (f *Hex) Marshal(v interface{}) error { - if v == nil { - return nil + switch v := v.(type) { + case *Hex: + if v == nil { + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = "" + return nil + } + + f.value = v + hex.EncodeToString([]byte(v)) + case *string: + if v == nil { + f.value = "" + return nil + } + + f.value = *v + case []byte: + f.SetBytes(v) + case *[]byte: + if v == nil { + f.value = "" + return nil + } + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Hex or (string, *string, []byte, *[]byte) type") } - str, ok := v.(*Hex) - if !ok { - return fmt.Errorf("data does not match required *Hex 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 25c4a96b..43f131c8 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,83 @@ 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} + str := NewHexValue("123456") + + val1 := &Hex{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, "123456", val1.Value()) + buf, _ := val1.Bytes() + require.Equal(t, testValue, buf) + + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + + var val3 []byte + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, testValue, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, testValue, val5.Bytes()) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Hex or (*string, *[]byte) type", err.Error()) +} + +func TestHexFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewHexValue("") + + vstring := "123456" + err := str.Marshal(vstring) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ := str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(&vstring) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(nil) + 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 7c17f1b1..21cc7ded 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,80 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str := strconv.Itoa(f.value) + val.SetString(str) + case reflect.Int: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetInt(int64(f.value)) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + str := strconv.Itoa(f.value) + *val = str + case *int: + *val = f.value + case *Numeric: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Numeric or *int type") } - num.value = f.value - return nil } -func (f *Numeric) Marshal(v interface{}) error { - if v == nil { - return nil - } +func (f *Numeric) Marshal(data interface{}) error { + switch v := data.(type) { + case *Numeric: + if v == nil { + f.value = 0 + return nil + } + f.value = v.value + case int: + f.value = v + case *int: + if v == nil { + f.value = 0 + return nil + } + f.value = *v + case string: + if v == "" { + f.value = 0 + return nil + } + val, err := strconv.Atoi(v) + if err != nil { + return utils.NewSafeError(err, "failed to convert sting value into number") + } + f.value = val + case *string: + if v == nil { + f.value = 0 + return nil + } - num, ok := v.(*Numeric) - if !ok { - return fmt.Errorf("data does not match required *Numeric type") + 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 1da167ea..8665652a 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,74 @@ func TestNumericPack(t *testing.T) { } func TestNumericFieldUnmarshal(t *testing.T) { - str := NewNumericValue(9876) + str := NewNumericValue(123456) + + val1 := &Numeric{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, 123456, val1.Value()) - val := &Numeric{} + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) - err := str.Unmarshal(val) + var val3 int + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, 123456, val3) + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) require.NoError(t, err) - require.Equal(t, 9876, val.Value()) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, 123456, int(val5.Int())) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Numeric or *int type", err.Error()) +} + +func TestNumericFieldMarshal(t *testing.T) { + str := NewNumericValue(0) + vNumeric := NewNumericValue(123456) + str.Marshal(vNumeric) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vNumeric) + require.Equal(t, 123456, vNumeric.Value()) + + vstring := "123456" + str.Marshal(vstring) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vstring) + require.Equal(t, 123456, vNumeric.Value()) + + vint := 123456 + str.Marshal(vint) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vint) + require.Equal(t, 123456, vNumeric.Value()) + + err := str.Marshal(nil) + 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 +226,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 11421e25..f20e564b 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,74 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetString(f.value) + case reflect.Int: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + 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 } func (f *String) Marshal(v interface{}) error { - if v == nil { - return nil + switch v := v.(type) { + case *String: + if v == nil { + f.value = "" + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = "" + return nil + } + f.value = v + case *string: + if v == nil { + f.value = "" + return nil + } + 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") } - str, ok := v.(*String) - if !ok { - return fmt.Errorf("data does not match required *String 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 2158d3ff..c8a11f38 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,74 @@ func TestStringPack(t *testing.T) { } func TestStringFieldUnmarshal(t *testing.T) { - str := NewStringValue("hello") + str := NewStringValue("123456") - val := &String{} + val1 := &String{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, "123456", val1.Value()) - err := str.Unmarshal(val) + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + var val3 int + err = str.Unmarshal(&val3) require.NoError(t, err) - require.Equal(t, "hello", val.Value()) + require.Equal(t, 123456, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, 123456, int(val5.Int())) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *String or *string type", err.Error()) +} + +func TestStringFieldMarshal(t *testing.T) { + str := NewStringValue("") + vString := NewStringValue("123456") + str.Marshal(vString) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vString) + require.Equal(t, "123456", str.Value()) + + vstring := "123456" + str.Marshal(vstring) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vstring) + require.Equal(t, "123456", str.Value()) + + vint := 123456 + str.Marshal(vint) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vint) + require.Equal(t, "123456", str.Value()) + + err := str.Marshal(nil) + 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) { From 91859e46984eed32d322287752cd1cfcd8b62974 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:34:34 -0500 Subject: [PATCH 04/13] fix test error --- field/composite_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/field/composite_test.go b/field/composite_test.go index 79939278..e32f79a6 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: data does not match required *String or *string type") }) t.Run("Unpack returns an error on failure of subfield to unpack bytes", func(t *testing.T) { From dff08c33ecea8500cd4427ed65ee0d27830686bb Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:24:20 -0500 Subject: [PATCH 05/13] Unpdate Unmarshal/Marshal method for the message and the rest of the fields --- field/binary.go | 95 +++++++++++++++++++++++++++++++------------ field/binary_test.go | 75 +++++++++++++++++++++++++++++++++- field/hex.go | 85 ++++++++++++++++++++++++++------------ field/hex_test.go | 81 ++++++++++++++++++++++++++++++++++++ field/numeric.go | 91 ++++++++++++++++++++++++++++++----------- field/numeric_test.go | 73 ++++++++++++++++++++++++++++++--- field/string.go | 87 +++++++++++++++++++++++++++------------ field/string_test.go | 80 ++++++++++++++++++++++++++++++------ 8 files changed, 548 insertions(+), 119 deletions(-) diff --git a/field/binary.go b/field/binary.go index d1813c51..7c9c3dfb 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,82 @@ func (f *Binary) SetData(data interface{}) error { } func (f *Binary) Unmarshal(v interface{}) error { - if v == nil { - return nil + switch val := v.(type) { + case reflect.Value: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str := hex.EncodeToString(f.value) + val.SetString(str) + case reflect.Slice: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetBytes(f.value) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + str := hex.EncodeToString(f.value) + *val = str + case *[]byte: + *val = f.value + case *Binary: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Binary or (*string, *[]byte) type") } - bin, ok := v.(*Binary) - if !ok { - return errors.New("data does not match required *Binary type") - } - - bin.value = f.value - return nil } func (f *Binary) Marshal(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 v := v.(type) { + case *Binary: + if v == nil { + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = nil + return nil + } + + buf, err := hex.DecodeString(v) + if err != nil { + return fmt.Errorf("failed to convert string to byte: %w", err) + } + + f.value = buf + case *string: + if v == nil { + f.value = nil + return nil + } + + 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: + if v == nil { + f.value = nil + return nil + } + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Binary or (string, *string, []byte, *[]byte) type") } - f.data = bin - if bin.value != nil { - f.value = bin.value - } return nil } diff --git a/field/binary_test.go b/field/binary_test.go index e3670ed3..6d300ba2 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,73 @@ func TestBinaryNil(t *testing.T) { bs = str.Value() require.Nil(t, bs) } + +func TestBinaryFieldUnmarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewBinaryValue(testValue) + + val1 := &Binary{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, testValue, val1.Value()) + + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + + var val3 []byte + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, testValue, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, testValue, val5.Bytes()) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Binary or (*string, *[]byte) type", err.Error()) +} + +func TestBinaryFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewBinaryValue(nil) + + vstring := "123456" + err := str.Marshal(vstring) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(&vstring) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, testValue, str.Value()) + + err = str.Marshal(nil) + 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/hex.go b/field/hex.go index 36d8b0f5..8912be17 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,73 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str, _ := f.String() + val.SetString(str) + case reflect.Slice: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + buf, _ := f.Bytes() + val.SetBytes(buf) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + *val, _ = f.String() + case *[]byte: + *val, _ = f.Bytes() + case *Hex: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Hex or (*string, *[]byte) type") } - str.value = f.value - return nil } func (f *Hex) Marshal(v interface{}) error { - if v == nil { - return nil + switch v := v.(type) { + case *Hex: + if v == nil { + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = "" + return nil + } + + f.value = v + hex.EncodeToString([]byte(v)) + case *string: + if v == nil { + f.value = "" + return nil + } + + f.value = *v + case []byte: + f.SetBytes(v) + case *[]byte: + if v == nil { + f.value = "" + return nil + } + f.SetBytes(*v) + default: + return fmt.Errorf("data does not match required *Hex or (string, *string, []byte, *[]byte) type") } - str, ok := v.(*Hex) - if !ok { - return fmt.Errorf("data does not match required *Hex 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 25c4a96b..43f131c8 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,83 @@ 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} + str := NewHexValue("123456") + + val1 := &Hex{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, "123456", val1.Value()) + buf, _ := val1.Bytes() + require.Equal(t, testValue, buf) + + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + + var val3 []byte + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, testValue, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, testValue, val5.Bytes()) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Hex or (*string, *[]byte) type", err.Error()) +} + +func TestHexFieldMarshal(t *testing.T) { + testValue := []byte{0x12, 0x34, 0x56} + str := NewHexValue("") + + vstring := "123456" + err := str.Marshal(vstring) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ := str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(&vstring) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(testValue) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(&testValue) + require.NoError(t, err) + require.Equal(t, "123456", str.Value()) + buf, _ = str.Bytes() + require.Equal(t, testValue, buf) + + err = str.Marshal(nil) + 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 7c17f1b1..21cc7ded 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,80 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + str := strconv.Itoa(f.value) + val.SetString(str) + case reflect.Int: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetInt(int64(f.value)) + default: + return fmt.Errorf("data does not match required reflect.Value type") + } + case *string: + str := strconv.Itoa(f.value) + *val = str + case *int: + *val = f.value + case *Numeric: + val.value = f.value + default: + return fmt.Errorf("data does not match required *Numeric or *int type") } - num.value = f.value - return nil } -func (f *Numeric) Marshal(v interface{}) error { - if v == nil { - return nil - } +func (f *Numeric) Marshal(data interface{}) error { + switch v := data.(type) { + case *Numeric: + if v == nil { + f.value = 0 + return nil + } + f.value = v.value + case int: + f.value = v + case *int: + if v == nil { + f.value = 0 + return nil + } + f.value = *v + case string: + if v == "" { + f.value = 0 + return nil + } + val, err := strconv.Atoi(v) + if err != nil { + return utils.NewSafeError(err, "failed to convert sting value into number") + } + f.value = val + case *string: + if v == nil { + f.value = 0 + return nil + } - num, ok := v.(*Numeric) - if !ok { - return fmt.Errorf("data does not match required *Numeric type") + 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 1da167ea..8665652a 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,74 @@ func TestNumericPack(t *testing.T) { } func TestNumericFieldUnmarshal(t *testing.T) { - str := NewNumericValue(9876) + str := NewNumericValue(123456) + + val1 := &Numeric{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, 123456, val1.Value()) - val := &Numeric{} + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) - err := str.Unmarshal(val) + var val3 int + err = str.Unmarshal(&val3) + require.NoError(t, err) + require.Equal(t, 123456, val3) + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) require.NoError(t, err) - require.Equal(t, 9876, val.Value()) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, 123456, int(val5.Int())) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *Numeric or *int type", err.Error()) +} + +func TestNumericFieldMarshal(t *testing.T) { + str := NewNumericValue(0) + vNumeric := NewNumericValue(123456) + str.Marshal(vNumeric) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vNumeric) + require.Equal(t, 123456, vNumeric.Value()) + + vstring := "123456" + str.Marshal(vstring) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vstring) + require.Equal(t, 123456, vNumeric.Value()) + + vint := 123456 + str.Marshal(vint) + require.Equal(t, 123456, vNumeric.Value()) + + str.Marshal(&vint) + require.Equal(t, 123456, vNumeric.Value()) + + err := str.Marshal(nil) + 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 +226,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 11421e25..f20e564b 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,74 @@ 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: + switch val.Kind() { //nolint:exhaustive + case reflect.String: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + val.SetString(f.value) + case reflect.Int: + if !val.CanSet() { + return fmt.Errorf("reflect.Value of the data can not be change") + } + + 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 } func (f *String) Marshal(v interface{}) error { - if v == nil { - return nil + switch v := v.(type) { + case *String: + if v == nil { + f.value = "" + return nil + } + f.value = v.value + case string: + if v == "" { + f.value = "" + return nil + } + f.value = v + case *string: + if v == nil { + f.value = "" + return nil + } + 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") } - str, ok := v.(*String) - if !ok { - return fmt.Errorf("data does not match required *String 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 2158d3ff..c8a11f38 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,74 @@ func TestStringPack(t *testing.T) { } func TestStringFieldUnmarshal(t *testing.T) { - str := NewStringValue("hello") + str := NewStringValue("123456") - val := &String{} + val1 := &String{} + err := str.Unmarshal(val1) + require.NoError(t, err) + require.Equal(t, "123456", val1.Value()) - err := str.Unmarshal(val) + var val2 string + err = str.Unmarshal(&val2) + require.NoError(t, err) + require.Equal(t, "123456", val2) + var val3 int + err = str.Unmarshal(&val3) require.NoError(t, err) - require.Equal(t, "hello", val.Value()) + require.Equal(t, 123456, val3) + + val4 := reflect.ValueOf(&val2).Elem() + err = str.Unmarshal(val4) + require.NoError(t, err) + require.Equal(t, "123456", val4.String()) + + val5 := reflect.ValueOf(&val3).Elem() + err = str.Unmarshal(val5) + require.NoError(t, err) + require.Equal(t, 123456, int(val5.Int())) + + val6 := reflect.ValueOf(val2) + err = str.Unmarshal(val6) + require.Error(t, err) + require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + + val7 := reflect.ValueOf(&val2) + err = str.Unmarshal(val7) + require.Error(t, err) + require.Equal(t, "data does not match required reflect.Value type", err.Error()) + + err = str.Unmarshal(nil) + require.Error(t, err) + require.Equal(t, "data does not match required *String or *string type", err.Error()) +} + +func TestStringFieldMarshal(t *testing.T) { + str := NewStringValue("") + vString := NewStringValue("123456") + str.Marshal(vString) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vString) + require.Equal(t, "123456", str.Value()) + + vstring := "123456" + str.Marshal(vstring) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vstring) + require.Equal(t, "123456", str.Value()) + + vint := 123456 + str.Marshal(vint) + require.Equal(t, "123456", str.Value()) + + str.Marshal(&vint) + require.Equal(t, "123456", str.Value()) + + err := str.Marshal(nil) + 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) { From 71792f0269ac77cc79fdb4f81c390347ca894087 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 10:34:34 -0500 Subject: [PATCH 06/13] fix test error --- field/composite_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/field/composite_test.go b/field/composite_test.go index 79939278..e32f79a6 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: data does not match required *String or *string type") }) t.Run("Unpack returns an error on failure of subfield to unpack bytes", func(t *testing.T) { From 08c56a1132c926567c718c0cb592ca05fa4a89b4 Mon Sep 17 00:00:00 2001 From: jose antonio <52543837+mfdeveloper508@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:54:41 -0500 Subject: [PATCH 07/13] change error message Co-authored-by: Pavel Gabriel --- field/binary.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/field/binary.go b/field/binary.go index 7c9c3dfb..6d600c58 100644 --- a/field/binary.go +++ b/field/binary.go @@ -134,7 +134,7 @@ func (f *Binary) Unmarshal(v interface{}) error { val.SetBytes(f.value) default: - return fmt.Errorf("data does not match required reflect.Value type") + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) } case *string: str := hex.EncodeToString(f.value) From adfa8888d85dd33874282e135fb2448c8308eafb Mon Sep 17 00:00:00 2001 From: jose antonio <52543837+mfdeveloper508@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:54:57 -0500 Subject: [PATCH 08/13] change error message Co-authored-by: Pavel Gabriel --- field/binary.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/field/binary.go b/field/binary.go index 6d600c58..4e1193d1 100644 --- a/field/binary.go +++ b/field/binary.go @@ -144,7 +144,7 @@ func (f *Binary) Unmarshal(v interface{}) error { case *Binary: val.value = f.value default: - return fmt.Errorf("data does not match required *Binary or (*string, *[]byte) type") + return fmt.Errorf("unsupported type: expected *Binary, *string, *[]byte, or reflect.Value, got %T", v) } return nil From 92096a346acf748c6359699757bc7946c0fcdad5 Mon Sep 17 00:00:00 2001 From: jose antonio <52543837+mfdeveloper508@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:55:13 -0500 Subject: [PATCH 09/13] code refactoring Co-authored-by: Pavel Gabriel --- field/binary.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/field/binary.go b/field/binary.go index 4e1193d1..d69ed538 100644 --- a/field/binary.go +++ b/field/binary.go @@ -137,8 +137,7 @@ func (f *Binary) Unmarshal(v interface{}) error { return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) } case *string: - str := hex.EncodeToString(f.value) - *val = str + *val = hex.EncodeToString(f.value) case *[]byte: *val = f.value case *Binary: From 0293e3a4dc2d3a3a65cebbc3fedc4531c4838812 Mon Sep 17 00:00:00 2001 From: jose antonio <52543837+mfdeveloper508@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:56:55 -0500 Subject: [PATCH 10/13] append error check Co-authored-by: Pavel Gabriel --- field/binary.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/field/binary.go b/field/binary.go index d69ed538..5e60e7e5 100644 --- a/field/binary.go +++ b/field/binary.go @@ -119,6 +119,10 @@ func (f *Binary) SetData(data interface{}) error { func (f *Binary) Unmarshal(v interface{}) error { 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: if !val.CanSet() { From 90dd1d98883993aa2df164f6c51f03a48eb4b603 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 14:51:24 -0500 Subject: [PATCH 11/13] code refactoring --- field/binary.go | 17 +++++++---------- field/binary_test.go | 6 +++--- field/bitmap.go | 2 +- field/composite_test.go | 2 +- field/hex.go | 22 +++++++++++----------- field/hex_test.go | 6 +++--- field/numeric.go | 16 ++++++---------- field/numeric_test.go | 6 +++--- field/string.go | 16 ++++++---------- field/string_test.go | 6 +++--- field/track1.go | 4 ++-- field/track2.go | 4 ++-- field/track3.go | 4 ++-- field/track_test.go | 6 +++--- 14 files changed, 53 insertions(+), 64 deletions(-) diff --git a/field/binary.go b/field/binary.go index 5e60e7e5..74509a7b 100644 --- a/field/binary.go +++ b/field/binary.go @@ -125,17 +125,8 @@ func (f *Binary) Unmarshal(v interface{}) error { switch val.Kind() { //nolint:exhaustive case reflect.String: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - - str := hex.EncodeToString(f.value) - val.SetString(str) + val.SetString(hex.EncodeToString(f.value)) case reflect.Slice: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - val.SetBytes(f.value) default: return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) @@ -185,12 +176,18 @@ func (f *Binary) Marshal(v interface{}) error { f.value = buf case []byte: + if v == nil || len(v) == 0 { + f.value = nil + return nil + } + f.SetBytes(v) case *[]byte: if v == nil { f.value = nil return nil } + f.SetBytes(*v) default: return fmt.Errorf("data does not match required *Binary or (string, *string, []byte, *[]byte) type") diff --git a/field/binary_test.go b/field/binary_test.go index 6d300ba2..a5a942eb 100644 --- a/field/binary_test.go +++ b/field/binary_test.go @@ -174,16 +174,16 @@ func TestBinaryFieldUnmarshal(t *testing.T) { val6 := reflect.ValueOf(val2) err = str.Unmarshal(val6) require.Error(t, err) - require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) val7 := reflect.ValueOf(&val2) err = str.Unmarshal(val7) require.Error(t, err) - require.Equal(t, "data does not match required reflect.Value type", err.Error()) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) err = str.Unmarshal(nil) require.Error(t, err) - require.Equal(t, "data does not match required *Binary or (*string, *[]byte) type", err.Error()) + require.Equal(t, "unsupported type: expected *Binary, *string, *[]byte, or reflect.Value, got ", err.Error()) } func TestBinaryFieldMarshal(t *testing.T) { diff --git a/field/bitmap.go b/field/bitmap.go index a8f0e170..d7f64acb 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 e32f79a6..1e8f8897 100644 --- a/field/composite_test.go +++ b/field/composite_test.go @@ -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 or *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 8912be17..6317a3f1 100644 --- a/field/hex.go +++ b/field/hex.go @@ -130,23 +130,19 @@ func (f *Hex) SetData(data interface{}) error { func (f *Hex) Unmarshal(v interface{}) error { 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: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - str, _ := f.String() val.SetString(str) case reflect.Slice: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - buf, _ := f.Bytes() val.SetBytes(buf) default: - return fmt.Errorf("data does not match required reflect.Value type") + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) } case *string: *val, _ = f.String() @@ -155,7 +151,7 @@ func (f *Hex) Unmarshal(v interface{}) error { case *Hex: val.value = f.value default: - return fmt.Errorf("data does not match required *Hex or (*string, *[]byte) type") + return fmt.Errorf("unsupported type: expected *Hex, *string, *[]byte, or reflect.Value, got %T", v) } return nil @@ -175,7 +171,6 @@ func (f *Hex) Marshal(v interface{}) error { } f.value = v - hex.EncodeToString([]byte(v)) case *string: if v == nil { f.value = "" @@ -184,6 +179,11 @@ func (f *Hex) Marshal(v interface{}) error { f.value = *v case []byte: + if v == nil || len(v) == 0 { + f.value = "" + return nil + } + f.SetBytes(v) case *[]byte: if v == nil { diff --git a/field/hex_test.go b/field/hex_test.go index 43f131c8..a5d766e0 100644 --- a/field/hex_test.go +++ b/field/hex_test.go @@ -178,16 +178,16 @@ func TestHexFieldUnmarshal(t *testing.T) { val6 := reflect.ValueOf(val2) err = str.Unmarshal(val6) require.Error(t, err) - require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) val7 := reflect.ValueOf(&val2) err = str.Unmarshal(val7) require.Error(t, err) - require.Equal(t, "data does not match required reflect.Value type", err.Error()) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) err = str.Unmarshal(nil) require.Error(t, err) - require.Equal(t, "data does not match required *Hex or (*string, *[]byte) type", err.Error()) + require.Equal(t, "unsupported type: expected *Hex, *string, *[]byte, or reflect.Value, got ", err.Error()) } func TestHexFieldMarshal(t *testing.T) { diff --git a/field/numeric.go b/field/numeric.go index 21cc7ded..4b3ea893 100644 --- a/field/numeric.go +++ b/field/numeric.go @@ -132,22 +132,18 @@ func (f *Numeric) SetData(data interface{}) error { func (f *Numeric) Unmarshal(v interface{}) error { 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: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - str := strconv.Itoa(f.value) val.SetString(str) case reflect.Int: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - val.SetInt(int64(f.value)) default: - return fmt.Errorf("data does not match required reflect.Value type") + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) } case *string: str := strconv.Itoa(f.value) @@ -157,7 +153,7 @@ func (f *Numeric) Unmarshal(v interface{}) error { case *Numeric: val.value = f.value default: - return fmt.Errorf("data does not match required *Numeric or *int type") + return fmt.Errorf("unsupported type: expected *Numeric, *int, or reflect.Value, got %T", v) } return nil diff --git a/field/numeric_test.go b/field/numeric_test.go index 8665652a..5ba0f8b6 100644 --- a/field/numeric_test.go +++ b/field/numeric_test.go @@ -119,16 +119,16 @@ func TestNumericFieldUnmarshal(t *testing.T) { val6 := reflect.ValueOf(val2) err = str.Unmarshal(val6) require.Error(t, err) - require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) val7 := reflect.ValueOf(&val2) err = str.Unmarshal(val7) require.Error(t, err) - require.Equal(t, "data does not match required reflect.Value type", err.Error()) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) err = str.Unmarshal(nil) require.Error(t, err) - require.Equal(t, "data does not match required *Numeric or *int type", err.Error()) + require.Equal(t, "unsupported type: expected *Numeric, *int, or reflect.Value, got ", err.Error()) } func TestNumericFieldMarshal(t *testing.T) { diff --git a/field/string.go b/field/string.go index f20e564b..d2170ba7 100644 --- a/field/string.go +++ b/field/string.go @@ -118,18 +118,14 @@ func (f *String) SetData(data interface{}) error { func (f *String) Unmarshal(v interface{}) error { 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: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - val.SetString(f.value) case reflect.Int: - if !val.CanSet() { - return fmt.Errorf("reflect.Value of the data can not be change") - } - i, err := strconv.Atoi(f.value) if err != nil { return fmt.Errorf("failed to convert string to int: %w", err) @@ -137,7 +133,7 @@ func (f *String) Unmarshal(v interface{}) error { val.SetInt(int64(i)) default: - return fmt.Errorf("data does not match required reflect.Value type") + return fmt.Errorf("unsupported reflect.Value type: %s", val.Kind()) } case *string: *val = f.value @@ -150,7 +146,7 @@ func (f *String) Unmarshal(v interface{}) error { case *String: val.value = f.value default: - return fmt.Errorf("data does not match required *String or *string type") + return fmt.Errorf("unsupported type: expected *String, *string, or reflect.Value, got %T", v) } return nil diff --git a/field/string_test.go b/field/string_test.go index c8a11f38..bb407f24 100644 --- a/field/string_test.go +++ b/field/string_test.go @@ -120,16 +120,16 @@ func TestStringFieldUnmarshal(t *testing.T) { val6 := reflect.ValueOf(val2) err = str.Unmarshal(val6) require.Error(t, err) - require.Equal(t, "reflect.Value of the data can not be change", err.Error()) + require.Equal(t, "cannot set reflect.Value of type string", err.Error()) val7 := reflect.ValueOf(&val2) err = str.Unmarshal(val7) require.Error(t, err) - require.Equal(t, "data does not match required reflect.Value type", err.Error()) + require.Equal(t, "cannot set reflect.Value of type ptr", err.Error()) err = str.Unmarshal(nil) require.Error(t, err) - require.Equal(t, "data does not match required *String or *string type", err.Error()) + require.Equal(t, "unsupported type: expected *String, *string, or reflect.Value, got ", err.Error()) } func TestStringFieldMarshal(t *testing.T) { diff --git a/field/track1.go b/field/track1.go index 519bd914..afc421d9 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 e94d6d26..ec4aea9f 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 86ac72b5..97390504 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 f52e2ab7..edab9e46 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) { From 8d7a07269857265d3dcefbda3ceab01352e07684 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 2 Oct 2023 14:59:31 -0500 Subject: [PATCH 12/13] checking nil or zero data --- field/binary.go | 28 +++++----------------------- field/binary_test.go | 3 +++ field/hex.go | 27 +++++---------------------- field/hex_test.go | 3 +++ field/numeric.go | 26 +++++++------------------- field/numeric_test.go | 3 +++ field/string.go | 17 +++++------------ field/string_test.go | 3 +++ 8 files changed, 34 insertions(+), 76 deletions(-) diff --git a/field/binary.go b/field/binary.go index 74509a7b..07a48708 100644 --- a/field/binary.go +++ b/field/binary.go @@ -145,18 +145,15 @@ func (f *Binary) Unmarshal(v interface{}) error { } func (f *Binary) Marshal(v interface{}) error { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = nil + return nil + } + switch v := v.(type) { case *Binary: - if v == nil { - return nil - } f.value = v.value case string: - if v == "" { - f.value = nil - return nil - } - buf, err := hex.DecodeString(v) if err != nil { return fmt.Errorf("failed to convert string to byte: %w", err) @@ -164,11 +161,6 @@ func (f *Binary) Marshal(v interface{}) error { f.value = buf case *string: - if v == nil { - f.value = nil - return nil - } - buf, err := hex.DecodeString(*v) if err != nil { return fmt.Errorf("failed to convert string to byte: %w", err) @@ -176,18 +168,8 @@ func (f *Binary) Marshal(v interface{}) error { f.value = buf case []byte: - if v == nil || len(v) == 0 { - f.value = nil - return nil - } - f.SetBytes(v) case *[]byte: - if v == nil { - f.value = nil - return nil - } - f.SetBytes(*v) default: return fmt.Errorf("data does not match required *Binary or (string, *string, []byte, *[]byte) type") diff --git a/field/binary_test.go b/field/binary_test.go index a5a942eb..9ae02b5d 100644 --- a/field/binary_test.go +++ b/field/binary_test.go @@ -208,6 +208,9 @@ func TestBinaryFieldMarshal(t *testing.T) { require.Equal(t, testValue, str.Value()) err = str.Marshal(nil) + require.NoError(t, err) + + err = str.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/hex.go b/field/hex.go index 6317a3f1..e9b15fbf 100644 --- a/field/hex.go +++ b/field/hex.go @@ -158,38 +158,21 @@ func (f *Hex) Unmarshal(v interface{}) error { } func (f *Hex) Marshal(v interface{}) error { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = "" + return nil + } + switch v := v.(type) { case *Hex: - if v == nil { - return nil - } f.value = v.value case string: - if v == "" { - f.value = "" - return nil - } - f.value = v case *string: - if v == nil { - f.value = "" - return nil - } - f.value = *v case []byte: - if v == nil || len(v) == 0 { - f.value = "" - return nil - } - f.SetBytes(v) case *[]byte: - if v == nil { - f.value = "" - return nil - } f.SetBytes(*v) default: return fmt.Errorf("data does not match required *Hex or (string, *string, []byte, *[]byte) type") diff --git a/field/hex_test.go b/field/hex_test.go index a5d766e0..a0c08511 100644 --- a/field/hex_test.go +++ b/field/hex_test.go @@ -220,6 +220,9 @@ func TestHexFieldMarshal(t *testing.T) { require.Equal(t, testValue, buf) err = str.Marshal(nil) + require.NoError(t, err) + + err = str.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 4b3ea893..d3e5e7d7 100644 --- a/field/numeric.go +++ b/field/numeric.go @@ -159,38 +159,26 @@ func (f *Numeric) Unmarshal(v interface{}) error { return nil } -func (f *Numeric) Marshal(data interface{}) error { - switch v := data.(type) { +func (f *Numeric) Marshal(v interface{}) error { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = 0 + return nil + } + + switch v := v.(type) { case *Numeric: - if v == nil { - f.value = 0 - return nil - } f.value = v.value case int: f.value = v case *int: - if v == nil { - f.value = 0 - return nil - } f.value = *v case string: - if v == "" { - f.value = 0 - return nil - } val, err := strconv.Atoi(v) if err != nil { return utils.NewSafeError(err, "failed to convert sting value into number") } f.value = val case *string: - if v == nil { - f.value = 0 - return nil - } - val, err := strconv.Atoi(*v) if err != nil { return utils.NewSafeError(err, "failed to convert sting value into number") diff --git a/field/numeric_test.go b/field/numeric_test.go index 5ba0f8b6..682014e4 100644 --- a/field/numeric_test.go +++ b/field/numeric_test.go @@ -155,6 +155,9 @@ func TestNumericFieldMarshal(t *testing.T) { require.Equal(t, 123456, vNumeric.Value()) err := str.Marshal(nil) + require.NoError(t, err) + + err = str.Marshal([]byte("123456")) require.Error(t, err) require.Equal(t, "data does not match require *Numeric or (int, *int, string, *string) type", err.Error()) } diff --git a/field/string.go b/field/string.go index d2170ba7..2e88199f 100644 --- a/field/string.go +++ b/field/string.go @@ -153,24 +153,17 @@ func (f *String) Unmarshal(v interface{}) error { } func (f *String) Marshal(v interface{}) error { + if v == nil || reflect.ValueOf(v).IsZero() { + f.value = "" + return nil + } + switch v := v.(type) { case *String: - if v == nil { - f.value = "" - return nil - } f.value = v.value case string: - if v == "" { - f.value = "" - return nil - } f.value = v case *string: - if v == nil { - f.value = "" - return nil - } f.value = *v case int: f.value = strconv.FormatInt(int64(v), 10) diff --git a/field/string_test.go b/field/string_test.go index bb407f24..a0f210b4 100644 --- a/field/string_test.go +++ b/field/string_test.go @@ -156,6 +156,9 @@ func TestStringFieldMarshal(t *testing.T) { require.Equal(t, "123456", str.Value()) err := str.Marshal(nil) + require.NoError(t, err) + + err = str.Marshal([]byte("123456")) require.Error(t, err) require.Equal(t, "data does not match required *String or (string, *string, int, *int) type", err.Error()) } From d39319ad51276943ff615857f8ccf74e5055e425 Mon Sep 17 00:00:00 2001 From: Jose Date: Wed, 4 Oct 2023 15:48:25 -0500 Subject: [PATCH 13/13] change naming --- field/binary_test.go | 66 ++++++++++++++++++------------------ field/hex_test.go | 76 ++++++++++++++++++++--------------------- field/numeric_test.go | 79 ++++++++++++++++++++++--------------------- field/string_test.go | 79 ++++++++++++++++++++++--------------------- 4 files changed, 151 insertions(+), 149 deletions(-) diff --git a/field/binary_test.go b/field/binary_test.go index 9ae02b5d..227de551 100644 --- a/field/binary_test.go +++ b/field/binary_test.go @@ -144,73 +144,73 @@ func TestBinaryNil(t *testing.T) { func TestBinaryFieldUnmarshal(t *testing.T) { testValue := []byte{0x12, 0x34, 0x56} - str := NewBinaryValue(testValue) + binaryField := NewBinaryValue(testValue) - val1 := &Binary{} - err := str.Unmarshal(val1) + vBinary := &Binary{} + err := binaryField.Unmarshal(vBinary) require.NoError(t, err) - require.Equal(t, testValue, val1.Value()) + require.Equal(t, testValue, vBinary.Value()) - var val2 string - err = str.Unmarshal(&val2) + var s string + err = binaryField.Unmarshal(&s) require.NoError(t, err) - require.Equal(t, "123456", val2) + require.Equal(t, "123456", s) - var val3 []byte - err = str.Unmarshal(&val3) + var b []byte + err = binaryField.Unmarshal(&b) require.NoError(t, err) - require.Equal(t, testValue, val3) + require.Equal(t, testValue, b) - val4 := reflect.ValueOf(&val2).Elem() - err = str.Unmarshal(val4) + refStrValue := reflect.ValueOf(&s).Elem() + err = binaryField.Unmarshal(refStrValue) require.NoError(t, err) - require.Equal(t, "123456", val4.String()) + require.Equal(t, "123456", refStrValue.String()) - val5 := reflect.ValueOf(&val3).Elem() - err = str.Unmarshal(val5) + refBytesValue := reflect.ValueOf(&b).Elem() + err = binaryField.Unmarshal(refBytesValue) require.NoError(t, err) - require.Equal(t, testValue, val5.Bytes()) + require.Equal(t, testValue, refBytesValue.Bytes()) - val6 := reflect.ValueOf(val2) - err = str.Unmarshal(val6) + refStr := reflect.ValueOf(s) + err = binaryField.Unmarshal(refStr) require.Error(t, err) require.Equal(t, "cannot set reflect.Value of type string", err.Error()) - val7 := reflect.ValueOf(&val2) - err = str.Unmarshal(val7) + 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 = str.Unmarshal(nil) + 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} - str := NewBinaryValue(nil) + binaryField := NewBinaryValue(nil) - vstring := "123456" - err := str.Marshal(vstring) + inputStr := "123456" + err := binaryField.Marshal(inputStr) require.NoError(t, err) - require.Equal(t, testValue, str.Value()) + require.Equal(t, testValue, binaryField.Value()) - err = str.Marshal(&vstring) + err = binaryField.Marshal(&inputStr) require.NoError(t, err) - require.Equal(t, testValue, str.Value()) + require.Equal(t, testValue, binaryField.Value()) - err = str.Marshal(testValue) + err = binaryField.Marshal(testValue) require.NoError(t, err) - require.Equal(t, testValue, str.Value()) + require.Equal(t, testValue, binaryField.Value()) - err = str.Marshal(&testValue) + err = binaryField.Marshal(&testValue) require.NoError(t, err) - require.Equal(t, testValue, str.Value()) + require.Equal(t, testValue, binaryField.Value()) - err = str.Marshal(nil) + err = binaryField.Marshal(nil) require.NoError(t, err) - err = str.Marshal(123456) + 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/hex_test.go b/field/hex_test.go index a0c08511..3b0edcbd 100644 --- a/field/hex_test.go +++ b/field/hex_test.go @@ -146,83 +146,83 @@ func TestHexPack(t *testing.T) { func TestHexFieldUnmarshal(t *testing.T) { testValue := []byte{0x12, 0x34, 0x56} - str := NewHexValue("123456") + hexField := NewHexValue("123456") - val1 := &Hex{} - err := str.Unmarshal(val1) + vHex := &Hex{} + err := hexField.Unmarshal(vHex) require.NoError(t, err) - require.Equal(t, "123456", val1.Value()) - buf, _ := val1.Bytes() + require.Equal(t, "123456", vHex.Value()) + buf, _ := vHex.Bytes() require.Equal(t, testValue, buf) - var val2 string - err = str.Unmarshal(&val2) + var s string + err = hexField.Unmarshal(&s) require.NoError(t, err) - require.Equal(t, "123456", val2) + require.Equal(t, "123456", s) - var val3 []byte - err = str.Unmarshal(&val3) + var b []byte + err = hexField.Unmarshal(&b) require.NoError(t, err) - require.Equal(t, testValue, val3) + require.Equal(t, testValue, b) - val4 := reflect.ValueOf(&val2).Elem() - err = str.Unmarshal(val4) + refStrValue := reflect.ValueOf(&s).Elem() + err = hexField.Unmarshal(refStrValue) require.NoError(t, err) - require.Equal(t, "123456", val4.String()) + require.Equal(t, "123456", refStrValue.String()) - val5 := reflect.ValueOf(&val3).Elem() - err = str.Unmarshal(val5) + refBytesValue := reflect.ValueOf(&b).Elem() + err = hexField.Unmarshal(refBytesValue) require.NoError(t, err) - require.Equal(t, testValue, val5.Bytes()) + require.Equal(t, testValue, refBytesValue.Bytes()) - val6 := reflect.ValueOf(val2) - err = str.Unmarshal(val6) + refStr := reflect.ValueOf(s) + err = hexField.Unmarshal(refStr) require.Error(t, err) require.Equal(t, "cannot set reflect.Value of type string", err.Error()) - val7 := reflect.ValueOf(&val2) - err = str.Unmarshal(val7) + 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 = str.Unmarshal(nil) + 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} - str := NewHexValue("") + hexField := NewHexValue("") - vstring := "123456" - err := str.Marshal(vstring) + inputStr := "123456" + err := hexField.Marshal(inputStr) require.NoError(t, err) - require.Equal(t, "123456", str.Value()) - buf, _ := str.Bytes() + require.Equal(t, "123456", hexField.Value()) + buf, _ := hexField.Bytes() require.Equal(t, testValue, buf) - err = str.Marshal(&vstring) + err = hexField.Marshal(&inputStr) require.NoError(t, err) - require.Equal(t, "123456", str.Value()) - buf, _ = str.Bytes() + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() require.Equal(t, testValue, buf) - err = str.Marshal(testValue) + err = hexField.Marshal(testValue) require.NoError(t, err) - require.Equal(t, "123456", str.Value()) - buf, _ = str.Bytes() + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() require.Equal(t, testValue, buf) - err = str.Marshal(&testValue) + err = hexField.Marshal(&testValue) require.NoError(t, err) - require.Equal(t, "123456", str.Value()) - buf, _ = str.Bytes() + require.Equal(t, "123456", hexField.Value()) + buf, _ = hexField.Bytes() require.Equal(t, testValue, buf) - err = str.Marshal(nil) + err = hexField.Marshal(nil) require.NoError(t, err) - err = str.Marshal(123456) + 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_test.go b/field/numeric_test.go index 682014e4..4845013b 100644 --- a/field/numeric_test.go +++ b/field/numeric_test.go @@ -89,75 +89,76 @@ func TestNumericPack(t *testing.T) { } func TestNumericFieldUnmarshal(t *testing.T) { - str := NewNumericValue(123456) + numericField := NewNumericValue(123456) - val1 := &Numeric{} - err := str.Unmarshal(val1) + vNumeric := &Numeric{} + err := numericField.Unmarshal(vNumeric) require.NoError(t, err) - require.Equal(t, 123456, val1.Value()) + require.Equal(t, 123456, vNumeric.Value()) - var val2 string - err = str.Unmarshal(&val2) + var s string + err = numericField.Unmarshal(&s) require.NoError(t, err) - require.Equal(t, "123456", val2) + require.Equal(t, "123456", s) - var val3 int - err = str.Unmarshal(&val3) + var b int + err = numericField.Unmarshal(&b) require.NoError(t, err) - require.Equal(t, 123456, val3) + require.Equal(t, 123456, b) - val4 := reflect.ValueOf(&val2).Elem() - err = str.Unmarshal(val4) + refStrValue := reflect.ValueOf(&s).Elem() + err = numericField.Unmarshal(refStrValue) require.NoError(t, err) - require.Equal(t, "123456", val4.String()) + require.Equal(t, "123456", refStrValue.String()) - val5 := reflect.ValueOf(&val3).Elem() - err = str.Unmarshal(val5) + refIntValue := reflect.ValueOf(&b).Elem() + err = numericField.Unmarshal(refIntValue) require.NoError(t, err) - require.Equal(t, 123456, int(val5.Int())) + require.Equal(t, 123456, int(refIntValue.Int())) - val6 := reflect.ValueOf(val2) - err = str.Unmarshal(val6) + refStr := reflect.ValueOf(s) + err = numericField.Unmarshal(refStr) require.Error(t, err) require.Equal(t, "cannot set reflect.Value of type string", err.Error()) - val7 := reflect.ValueOf(&val2) - err = str.Unmarshal(val7) + 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 = str.Unmarshal(nil) + 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) { - str := NewNumericValue(0) - vNumeric := NewNumericValue(123456) - str.Marshal(vNumeric) - require.Equal(t, 123456, vNumeric.Value()) + numericField := NewNumericValue(0) - str.Marshal(&vNumeric) - require.Equal(t, 123456, vNumeric.Value()) + inputNumeric := NewNumericValue(123456) + numericField.Marshal(inputNumeric) + require.Equal(t, 123456, numericField.Value()) - vstring := "123456" - str.Marshal(vstring) - require.Equal(t, 123456, vNumeric.Value()) + numericField.Marshal(&inputNumeric) + require.Equal(t, 123456, numericField.Value()) - str.Marshal(&vstring) - require.Equal(t, 123456, vNumeric.Value()) + inputStr := "123456" + numericField.Marshal(inputStr) + require.Equal(t, 123456, numericField.Value()) - vint := 123456 - str.Marshal(vint) - require.Equal(t, 123456, vNumeric.Value()) + numericField.Marshal(&inputStr) + require.Equal(t, 123456, numericField.Value()) - str.Marshal(&vint) - require.Equal(t, 123456, vNumeric.Value()) + inputInt := 123456 + numericField.Marshal(inputInt) + require.Equal(t, 123456, numericField.Value()) + + numericField.Marshal(&inputInt) + require.Equal(t, 123456, numericField.Value()) - err := str.Marshal(nil) + err := numericField.Marshal(nil) require.NoError(t, err) - err = str.Marshal([]byte("123456")) + 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()) } diff --git a/field/string_test.go b/field/string_test.go index a0f210b4..01d1b092 100644 --- a/field/string_test.go +++ b/field/string_test.go @@ -90,75 +90,76 @@ func TestStringPack(t *testing.T) { } func TestStringFieldUnmarshal(t *testing.T) { - str := NewStringValue("123456") + stringField := NewStringValue("123456") - val1 := &String{} - err := str.Unmarshal(val1) + vString := &String{} + err := stringField.Unmarshal(vString) require.NoError(t, err) - require.Equal(t, "123456", val1.Value()) + require.Equal(t, "123456", vString.Value()) - var val2 string - err = str.Unmarshal(&val2) + var s string + err = stringField.Unmarshal(&s) require.NoError(t, err) - require.Equal(t, "123456", val2) + require.Equal(t, "123456", s) - var val3 int - err = str.Unmarshal(&val3) + var b int + err = stringField.Unmarshal(&b) require.NoError(t, err) - require.Equal(t, 123456, val3) + require.Equal(t, 123456, b) - val4 := reflect.ValueOf(&val2).Elem() - err = str.Unmarshal(val4) + refStrValue := reflect.ValueOf(&s).Elem() + err = stringField.Unmarshal(refStrValue) require.NoError(t, err) - require.Equal(t, "123456", val4.String()) + require.Equal(t, "123456", refStrValue.String()) - val5 := reflect.ValueOf(&val3).Elem() - err = str.Unmarshal(val5) + refIntValue := reflect.ValueOf(&b).Elem() + err = stringField.Unmarshal(refIntValue) require.NoError(t, err) - require.Equal(t, 123456, int(val5.Int())) + require.Equal(t, 123456, int(refIntValue.Int())) - val6 := reflect.ValueOf(val2) - err = str.Unmarshal(val6) + refStr := reflect.ValueOf(s) + err = stringField.Unmarshal(refStr) require.Error(t, err) require.Equal(t, "cannot set reflect.Value of type string", err.Error()) - val7 := reflect.ValueOf(&val2) - err = str.Unmarshal(val7) + 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 = str.Unmarshal(nil) + 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) { - str := NewStringValue("") - vString := NewStringValue("123456") - str.Marshal(vString) - require.Equal(t, "123456", str.Value()) + stringField := NewStringValue("") - str.Marshal(&vString) - require.Equal(t, "123456", str.Value()) + inputString := NewStringValue("123456") + stringField.Marshal(inputString) + require.Equal(t, "123456", stringField.Value()) - vstring := "123456" - str.Marshal(vstring) - require.Equal(t, "123456", str.Value()) + stringField.Marshal(&inputString) + require.Equal(t, "123456", stringField.Value()) - str.Marshal(&vstring) - require.Equal(t, "123456", str.Value()) + inputStr := "123456" + stringField.Marshal(inputStr) + require.Equal(t, "123456", stringField.Value()) - vint := 123456 - str.Marshal(vint) - require.Equal(t, "123456", str.Value()) + stringField.Marshal(&inputStr) + require.Equal(t, "123456", stringField.Value()) - str.Marshal(&vint) - require.Equal(t, "123456", str.Value()) + inputInt := 123456 + stringField.Marshal(inputInt) + require.Equal(t, "123456", stringField.Value()) - err := str.Marshal(nil) + stringField.Marshal(&inputInt) + require.Equal(t, "123456", stringField.Value()) + + err := stringField.Marshal(nil) require.NoError(t, err) - err = str.Marshal([]byte("123456")) + 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()) }