Skip to content

Commit

Permalink
field: nil check Numeric, String, Composite, etc accessors (#196)
Browse files Browse the repository at this point in the history
* field: nil check Numeric, String, Composite, etc and add GetValue()

Issue: #195

* field: convert .Value into a safe data accessor

* update README

Co-authored-by: Pavel Gabriel <alovak@gmail.com>
  • Loading branch information
adamdecaf and alovak authored Sep 26, 2022
1 parent 986a81f commit c45c72b
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 186 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ err = message.Unmarshal(data)
// handle error

// now you can access field values
data.MTI.Value // "0100"
data.TransmissionDateTime.Value // "220102103212"
data.STAN.Value // "000001"
data.InformationCode.Value // "001"
data.MTI.Value() // "0100"
data.TransmissionDateTime.Value() // "220102103212"
data.STAN.Value() // "000001"
data.InformationCode.Value() // "001"
```

For complete code samples please check [./message_test.go](./message_test.go).
Expand Down
31 changes: 22 additions & 9 deletions field/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var _ json.Marshaler = (*Binary)(nil)
var _ json.Unmarshaler = (*Binary)(nil)

type Binary struct {
Value []byte `json:"value"`
value []byte
spec *Spec
data *Binary
}
Expand All @@ -27,7 +27,7 @@ func NewBinary(spec *Spec) *Binary {

func NewBinaryValue(val []byte) *Binary {
return &Binary{
Value: val,
value: val,
}
}

Expand All @@ -40,23 +40,36 @@ func (f *Binary) SetSpec(spec *Spec) {
}

func (f *Binary) SetBytes(b []byte) error {
f.Value = b
f.value = b
if f.data != nil {
*(f.data) = *f
}
return nil
}

func (f *Binary) Bytes() ([]byte, error) {
return f.Value, nil
if f == nil {
return nil, nil
}
return f.value, nil
}

func (f *Binary) String() (string, error) {
return fmt.Sprintf("%X", f.Value), nil
if f == nil {
return "", nil
}
return fmt.Sprintf("%X", f.value), nil
}

func (f *Binary) Value() []byte {
if f == nil {
return nil
}
return f.value
}

func (f *Binary) Pack() ([]byte, error) {
data := f.Value
data := f.value

if f.spec.Pad != nil {
data = f.spec.Pad.Pad(data, f.spec.Length)
Expand Down Expand Up @@ -107,7 +120,7 @@ func (f *Binary) Unmarshal(v interface{}) error {
return errors.New("data does not match required *Binary type")
}

bin.Value = f.Value
bin.value = f.value

return nil
}
Expand All @@ -123,8 +136,8 @@ func (f *Binary) SetData(data interface{}) error {
}

f.data = bin
if bin.Value != nil {
f.Value = bin.Value
if bin.value != nil {
f.value = bin.value
}
return nil
}
Expand Down
25 changes: 20 additions & 5 deletions field/binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestBinaryField(t *testing.T) {

t.Run("String returns binary data encoded in HEX", func(t *testing.T) {
bin := NewBinary(spec)
bin.Value = in
bin.value = in

str, err := bin.String()

Expand All @@ -45,7 +45,7 @@ func TestBinaryField(t *testing.T) {

require.NoError(t, err)
require.Equal(t, len(in), n)
require.Equal(t, in, bin.Value)
require.Equal(t, in, bin.value)
})

t.Run("SetData sets data to the field", func(t *testing.T) {
Expand All @@ -65,7 +65,7 @@ func TestBinaryField(t *testing.T) {
err := bin.Unmarshal(val)

require.NoError(t, err)
require.Equal(t, []byte{1, 2, 3}, val.Value)
require.Equal(t, []byte{1, 2, 3}, val.value)
})

t.Run("SetBytes sets data to the data field", func(t *testing.T) {
Expand All @@ -76,7 +76,7 @@ func TestBinaryField(t *testing.T) {
err := bin.SetBytes(in)
require.NoError(t, err)

require.Equal(t, in, data.Value)
require.Equal(t, in, data.value)
})

t.Run("Unpack sets data to data value", func(t *testing.T) {
Expand All @@ -88,7 +88,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, data.value)
})

t.Run("UnmarshalJSON unquotes input before handling it", func(t *testing.T) {
Expand Down Expand Up @@ -117,3 +117,18 @@ func TestBinaryField(t *testing.T) {
require.EqualError(t, err, "failed to encode length: field length: 0 should be fixed: 10")
})
}

func TestBinaryNil(t *testing.T) {
var str *Binary = nil

bs, err := str.Bytes()
require.NoError(t, err)
require.Nil(t, bs)

value, err := str.String()
require.NoError(t, err)
require.Equal(t, "", value)

bs = str.Value()
require.Nil(t, bs)
}
6 changes: 6 additions & 0 deletions field/bitmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ func (f *Bitmap) SetBytes(b []byte) error {
}

func (f *Bitmap) Bytes() ([]byte, error) {
if f == nil {
return nil, nil
}
return f.bitmap.Bytes(), nil
}

func (f *Bitmap) String() (string, error) {
if f == nil {
return "", nil
}
return f.bitmap.String(), nil
}

Expand Down
12 changes: 12 additions & 0 deletions field/bitmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,15 @@ func TestBitmap_SetData(t *testing.T) {
require.Equal(t, []byte("a"), b)
})
}

func TestBitmapNil(t *testing.T) {
var str *Bitmap = nil

bs, err := str.Bytes()
require.NoError(t, err)
require.Nil(t, bs)

value, err := str.String()
require.NoError(t, err)
require.Equal(t, "", value)
}
52 changes: 26 additions & 26 deletions field/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ func TestCompositeFieldUnmarshal(t *testing.T) {
err = composite.Unmarshal(data)
require.NoError(t, err)

require.Equal(t, "210720", data.F9A.Value)
require.Equal(t, "000000000501", data.F9F02.Value)
require.Equal(t, "210720", data.F9A.Value())
require.Equal(t, "000000000501", data.F9F02.Value())
})

t.Run("Unmarshal gets data for composite field using field tag `index`", func(t *testing.T) {
Expand All @@ -220,8 +220,8 @@ func TestCompositeFieldUnmarshal(t *testing.T) {
err = composite.Unmarshal(data)
require.NoError(t, err)

require.Equal(t, "210720", data.Date.Value)
require.Equal(t, "000000000501", data.TransactionID.Value)
require.Equal(t, "210720", data.Date.Value())
require.Equal(t, "000000000501", data.TransactionID.Value())
})
}

Expand Down Expand Up @@ -261,8 +261,8 @@ func TestTLVPacking(t *testing.T) {
data := &TLVTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "210720", data.F9A.Value)
require.Equal(t, "000000000501", data.F9F02.Value)
require.Equal(t, "210720", data.F9A.Value())
require.Equal(t, "000000000501", data.F9F02.Value())
})
}

Expand Down Expand Up @@ -509,9 +509,9 @@ func TestCompositePacking(t *testing.T) {
data := &CompositeTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "CD", data.F2.Value)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, "AB", data.F1.Value())
require.Equal(t, "CD", data.F2.Value())
require.Equal(t, 12, data.F3.Value())
require.Nil(t, data.F11)
})

Expand All @@ -524,9 +524,9 @@ func TestCompositePacking(t *testing.T) {
data := &CompositeTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "CD", data.F2.Value)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, "AB", data.F1.Value())
require.Equal(t, "CD", data.F2.Value())
require.Equal(t, 12, data.F3.Value())
require.Nil(t, data.F11)
})
}
Expand Down Expand Up @@ -725,10 +725,10 @@ func TestCompositePackingWithTags(t *testing.T) {
data := &CompositeTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "CD", data.F2.Value)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, "YZ", data.F11.F1.Value)
require.Equal(t, "AB", data.F1.Value())
require.Equal(t, "CD", data.F2.Value())
require.Equal(t, 12, data.F3.Value())
require.Equal(t, "YZ", data.F11.F1.Value())
})

t.Run("Unpack correctly deserialises out of order composite subfields to the unpadded data struct", func(t *testing.T) {
Expand All @@ -743,8 +743,8 @@ func TestCompositePackingWithTags(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 14, read)

require.Equal(t, "AB", data.F01.Value)
require.Equal(t, "CD", data.F02.Value)
require.Equal(t, "AB", data.F01.Value())
require.Equal(t, "CD", data.F02.Value())
})

t.Run("Unpack correctly deserialises partial subfields to the data struct", func(t *testing.T) {
Expand All @@ -758,9 +758,9 @@ func TestCompositePackingWithTags(t *testing.T) {
data := &CompositeTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "AB", data.F1.Value())
require.Nil(t, data.F2)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, 12, data.F3.Value())
})

t.Run("Unpack correctly ignores excess bytes in excess of the length described by the prefix", func(t *testing.T) {
Expand All @@ -776,9 +776,9 @@ func TestCompositePackingWithTags(t *testing.T) {
data := &CompositeTestData{}
require.NoError(t, composite.Unmarshal(data))

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "CD", data.F2.Value)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, "AB", data.F1.Value())
require.Equal(t, "CD", data.F2.Value())
require.Equal(t, 12, data.F3.Value())
require.Nil(t, data.F11)
})
}
Expand Down Expand Up @@ -952,10 +952,10 @@ func TestCompositeJSONConversion(t *testing.T) {

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

require.Equal(t, "AB", data.F1.Value)
require.Equal(t, "AB", data.F1.Value())
require.Nil(t, data.F2)
require.Equal(t, 12, data.F3.Value)
require.Equal(t, "YZ", data.F11.F1.Value)
require.Equal(t, 12, data.F3.Value())
require.Equal(t, "YZ", data.F11.F1.Value())
})

t.Run("MarshalJSON untyped", func(t *testing.T) {
Expand Down
Loading

0 comments on commit c45c72b

Please sign in to comment.