Skip to content

Commit

Permalink
feat(go): marshaling/unmarshalling metadata fields in items
Browse files Browse the repository at this point in the history
  • Loading branch information
rot1024 committed Oct 26, 2023
1 parent 6f3221c commit 9e99f3e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 6 deletions.
46 changes: 40 additions & 6 deletions go/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ type Item struct {
ID string `json:"id"`
ModelID string `json:"modelId"`
Fields []Field `json:"fields"`
MetadataFields []Field `json:"metadataFields"`
MetadataFields []Field `json:"metadataFields,omitempty"`
}

func (i *Item) Clone() *Item {
Expand All @@ -118,6 +118,14 @@ func (i Item) Field(id string) *Field {
return nil
}

func (i Item) MetadataField(id string) *Field {
f, ok := lo.Find(i.MetadataFields, func(f Field) bool { return f.ID == id })
if ok {
return &f
}
return nil
}

func (i Item) FieldByKey(key string) *Field {
f, ok := lo.Find(i.Fields, func(f Field) bool { return f.Key == key })
if ok {
Expand All @@ -126,6 +134,14 @@ func (i Item) FieldByKey(key string) *Field {
return nil
}

func (i Item) MetadataFieldByKey(key string) *Field {
f, ok := lo.Find(i.MetadataFields, func(f Field) bool { return f.Key == key })
if ok {
return &f
}
return nil
}

func (d Item) Unmarshal(i any) {
if i == nil {
return
Expand All @@ -146,11 +162,13 @@ func (d Item) Unmarshal(i any) {
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := f.Tag.Get(tag)
key, _, _ := strings.Cut(tag, ",")
key, opts, _ := strings.Cut(tag, ",")
if key == "" || key == "-" {
continue
}

isMetadata := strings.Contains(opts, ",metadata")

vf := v.FieldByName(f.Name)
if !vf.CanSet() {
continue
Expand All @@ -163,7 +181,14 @@ func (d Item) Unmarshal(i any) {
continue
}

if itf := d.FieldByKey(key); itf != nil {
var itf *Field
if isMetadata {
itf = d.MetadataFieldByKey(key)
} else {
itf = d.FieldByKey(key)
}

if itf != nil {
if f.Type.Kind() == reflect.String {
if itfv := itf.ValueString(); itfv != nil {
vf.SetString(*itfv)
Expand Down Expand Up @@ -210,11 +235,14 @@ func Marshal(i any, item *Item) {
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := f.Tag.Get(tag)
key, ty, _ := strings.Cut(tag, ",")
key, opts, _ := strings.Cut(tag, ",")
if key == "" || key == "-" {
continue
}

isMetadata := strings.Contains(opts, ",metadata")
ty, _, _ := strings.Cut(opts, ",")

vf := v.FieldByName(f.Name)
if key == "id" {
ni.ID, _ = vf.Interface().(string)
Expand All @@ -239,11 +267,17 @@ func Marshal(i any, item *Item) {
}

if i != nil {
ni.Fields = append(ni.Fields, Field{
f := Field{
Key: key,
Type: ty,
Value: i,
})
}

if isMetadata {
ni.MetadataFields = append(ni.MetadataFields, f)
} else {
ni.Fields = append(ni.Fields, f)
}
}
}

Expand Down
44 changes: 44 additions & 0 deletions go/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func TestItem_Unmarshal(t *testing.T) {
BBB []string `cms:"bbb"`
CCC []str `cms:"ccc"`
DDD map[string]any `cms:"ddd"`
EEE string `cms:"eee,,metadata"`
}
s := S{}

Expand All @@ -27,13 +28,17 @@ func TestItem_Unmarshal(t *testing.T) {
{Key: "ccc", Value: []string{"a", "b"}},
{Key: "ddd", Value: map[string]any{"a": "b"}},
},
MetadataFields: []Field{
{Key: "eee", Value: "xxx"},
},
}.Unmarshal(&s)
assert.Equal(t, S{
ID: "xxx",
AAA: "bbb",
BBB: []string{"ccc", "bbb"},
CCC: []str{"a", "b"},
DDD: map[string]any{"a": "b"},
EEE: "xxx",
}, s)

// no panic
Expand All @@ -51,13 +56,15 @@ func TestMarshal(t *testing.T) {
CCC str `cms:"ccc"`
DDD []str `cms:"ddd"`
EEE string `cms:"eee,text"`
FFF string `cms:"fff,text,metadata"`
}
s := S{
ID: "xxx",
AAA: "bbb",
BBB: []string{"ccc", "bbb"},
CCC: str("x"),
DDD: []str{"1", "2"},
FFF: "fff",
}
i := &Item{
ID: "xxx",
Expand All @@ -68,6 +75,9 @@ func TestMarshal(t *testing.T) {
{Key: "ddd", Type: "", Value: []string{"1", "2"}},
// no field for eee
},
MetadataFields: []Field{
{Key: "fff", Type: "text", Value: "fff"},
},
}

item := &Item{}
Expand Down Expand Up @@ -102,6 +112,23 @@ func TestItem_Field(t *testing.T) {
}.Field("ccc"))
}

func TestItem_MetadataField(t *testing.T) {
assert.Equal(t, &Field{
ID: "bbb", Value: "ccc", Type: "string",
}, Item{
MetadataFields: []Field{
{ID: "aaa", Value: "bbb", Type: "string"},
{ID: "bbb", Value: "ccc", Type: "string"},
},
}.MetadataField("bbb"))
assert.Nil(t, Item{
MetadataFields: []Field{
{ID: "aaa", Key: "bbb", Type: "string"},
{ID: "bbb", Key: "ccc", Type: "string"},
},
}.MetadataField("ccc"))
}

func TestItem_FieldByKey(t *testing.T) {
assert.Equal(t, &Field{
ID: "bbb", Key: "ccc", Type: "string",
Expand All @@ -119,6 +146,23 @@ func TestItem_FieldByKey(t *testing.T) {
}.FieldByKey("bbb"))
}

func TestItem_MetadataFieldByKey(t *testing.T) {
assert.Equal(t, &Field{
ID: "bbb", Key: "ccc", Type: "string",
}, Item{
MetadataFields: []Field{
{ID: "aaa", Key: "bbb", Type: "string"},
{ID: "bbb", Key: "ccc", Type: "string"},
},
}.MetadataFieldByKey("ccc"))
assert.Nil(t, Item{
MetadataFields: []Field{
{ID: "aaa", Key: "aaa", Type: "string"},
{ID: "bbb", Key: "ccc", Type: "string"},
},
}.MetadataFieldByKey("bbb"))
}

func TestField_ValueString(t *testing.T) {
assert.Equal(t, lo.ToPtr("ccc"), (&Field{
Value: "ccc",
Expand Down

0 comments on commit 9e99f3e

Please sign in to comment.