Skip to content

Commit

Permalink
Marshal the shared.Date time value
Browse files Browse the repository at this point in the history
Currently only IsMalformed is being stored in Dynamo, as it only uses named
fields. Since a shared.Date where IsMalformed is true will give an error to
whatever is creating it I have chosen to Marshal as a date string.
  • Loading branch information
hawx committed Jan 8, 2024
1 parent 56ba8d3 commit a8c7def
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 20 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ require (

require (
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.12.14 // indirect
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 // indirect
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.18.7 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@ github.com/aws/aws-sdk-go v1.49.13 h1:f4mGztsgnx2dR9r8FQYa9YW/RsKb+N7bgef4UGrOW1
github.com/aws/aws-sdk-go v1.49.13/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go v1.49.15 h1:aH9bSV4kL4ziH0AMtuYbukGIVebXddXBL0cKZ1zj15k=
github.com/aws/aws-sdk-go v1.49.15/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.12.14 h1:FpgWcv1aqU3xXbMVwEBr2sCeRT1Cctwqg/sWMI4wLoo=
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.12.14/go.mod h1:J2zgl/oFM9OWQoaEATWvh426859hrB1cuVEqLgGpi+Q=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 h1:XKO0BswTDeZMLDBd/b5pCEZGttNXrzRUVtFvp2Ak/Vo=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8/go.mod h1:N5tqZcYMM0N1PN7UQYJNWuGyO886OfnMhf/3MAbqMcI=
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.18.7 h1:srShyROqxzC7p18Ws8mqM2sqxJO/8L3Kpiqf+NboJLg=
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.18.7/go.mod h1:9efZgg4nJCGRp91MuHhkwd2kvyp7PWLRYYk5WjEQ5ts=
github.com/aws/aws-xray-sdk-go v1.8.3 h1:S8GdgVncBRhzbNnNUgTPwhEqhwt2alES/9rLASyhxjU=
github.com/aws/aws-xray-sdk-go v1.8.3/go.mod h1:tv8uLMOSCABolrIF8YCcp3ghyswArsan8dfLCA1ZATk=
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
42 changes: 35 additions & 7 deletions internal/shared/date.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,50 @@ package shared

import (
"time"

"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

type Date struct {
time.Time
IsMalformed bool
}

func (m *Date) UnmarshalJSON(data []byte) error {
str := string(data)
time, err := time.Parse(`"2006-01-02"`, str)

m.Time = time
func (d *Date) UnmarshalJSON(data []byte) error {
end := len(data) - 1
if len(data) <= 2 || data[0] != '"' || data[end] != '"' {
d.IsMalformed = len(data) != 0 && len(data) != 2 && data[0] != '"' && data[end] != '"'
return nil
}

if err != nil {
m.IsMalformed = str != "" && str != `""`
if err := d.UnmarshalText(data[1:end]); err != nil {
d.IsMalformed = true
}

return nil
}

func (d *Date) UnmarshalText(data []byte) error {
var err error
d.Time, err = time.Parse(time.DateOnly, string(data))
return err
}

func (d *Date) UnmarshalDynamoDBAttributeValue(av types.AttributeValue) error {
var s string
if err := attributevalue.Unmarshal(av, &s); err != nil {
return err
}

return d.UnmarshalText([]byte(s))
}

func (d Date) MarshalDynamoDBAttributeValue() (types.AttributeValue, error) {
text := ""
if !d.IsZero() {
text = d.Time.Format(time.DateOnly)
}

return attributevalue.Marshal(text)
}
48 changes: 35 additions & 13 deletions internal/shared/date_test.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,73 @@
package shared

import (
"encoding/json"
"testing"
"time"

"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/stretchr/testify/assert"
)

func TestUnmarshalDate(t *testing.T) {
testCases := []struct {
testCases := map[string]struct {
name string
in string
expectFormatted string
expectIsMalformed bool
}{
{
name: "ok",
"ok": {
in: `"1930-10-31"`,
expectFormatted: "31 October 1930",
expectIsMalformed: false,
},
{
name: "out of bounds",
"out of bounds": {
in: `"1930-11-31"`,
expectFormatted: "1 January 0001",
expectIsMalformed: true,
},
{
name: "invalid string",
"invalid string": {
in: `"31 October 1930"`,
expectFormatted: "1 January 0001",
expectIsMalformed: true,
},
{
name: "number",
"number": {
in: `1700240133`,
expectFormatted: "1 January 0001",
expectIsMalformed: true,
},
"empty string": {
in: `""`,
expectFormatted: "1 January 0001",
expectIsMalformed: false,
},
"space": {
in: `" "`,
expectFormatted: "1 January 0001",
expectIsMalformed: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
date := Date{}
date.UnmarshalJSON([]byte(tc.in))
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
var date Date
err := json.Unmarshal([]byte(tc.in), &date)

assert.Nil(t, err)
assert.Equal(t, tc.expectFormatted, date.Time.Format("2 January 2006"))
assert.Equal(t, tc.expectIsMalformed, date.IsMalformed)
})
}
}

func TestDateDynamoDB(t *testing.T) {
in := &types.AttributeValueMemberS{Value: "2000-01-02"}

var v Date
attributevalue.Unmarshal(in, &v)
assert.Equal(t, Date{Time: time.Date(2000, time.January, 2, 0, 0, 0, 0, time.UTC)}, v)

out, _ := attributevalue.Marshal(v)
assert.Equal(t, in, out)
}

0 comments on commit a8c7def

Please sign in to comment.