From 366d3d89af73033cc65b3c25d1041d6e4c09d60d Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 22 Jul 2022 08:45:16 +0700 Subject: [PATCH] support generics --- go.mod | 2 +- mapslice.go | 29 +++++++++++++++-------------- mapslice_test.go | 16 ++++++++-------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 4d5a3d4..4509b28 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ake-persson/mapslice-json -go 1.16 +go 1.18 require ( github.com/client9/misspell v0.3.4 // indirect diff --git a/mapslice.go b/mapslice.go index cdd4291..7012858 100644 --- a/mapslice.go +++ b/mapslice.go @@ -8,17 +8,18 @@ import ( ) // MapItem representation of one map item. -type MapItem struct { - Key, Value interface{} - index uint64 +type MapItem[V any] struct { + Key string + Value V + index uint64 } // MapSlice of map items. -type MapSlice []MapItem +type MapSlice[V any] []MapItem[V] -func (ms MapSlice) Len() int { return len(ms) } -func (ms MapSlice) Less(i, j int) bool { return ms[i].index < ms[j].index } -func (ms MapSlice) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } +func (ms MapSlice[V]) Len() int { return len(ms) } +func (ms MapSlice[V]) Less(i, j int) bool { return ms[i].index < ms[j].index } +func (ms MapSlice[V]) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } var indexCounter uint64 @@ -28,12 +29,12 @@ func nextIndex() uint64 { } // MapItem as a string. -func (mi MapItem) String() string { +func (mi MapItem[V]) String() string { return fmt.Sprintf("{%v %v}", mi.Key, mi.Value) } // MarshalJSON for map slice. -func (ms MapSlice) MarshalJSON() ([]byte, error) { +func (ms MapSlice[V]) MarshalJSON() ([]byte, error) { buf := &bytes.Buffer{} buf.Write([]byte{'{'}) for i, mi := range ms { @@ -52,21 +53,21 @@ func (ms MapSlice) MarshalJSON() ([]byte, error) { } // UnmarshalJSON for map slice. -func (ms *MapSlice) UnmarshalJSON(b []byte) error { - m := map[string]MapItem{} +func (ms *MapSlice[V]) UnmarshalJSON(b []byte) error { + m := map[string]MapItem[V]{} if err := json.Unmarshal(b, &m); err != nil { return err } for k, v := range m { - *ms = append(*ms, MapItem{Key: k, Value: v.Value, index: v.index}) + *ms = append(*ms, MapItem[V]{Key: k, Value: v.Value, index: v.index}) } sort.Sort(*ms) return nil } // UnmarshalJSON for map item. -func (mi *MapItem) UnmarshalJSON(b []byte) error { - var v interface{} +func (mi *MapItem[V]) UnmarshalJSON(b []byte) error { + var v V if err := json.Unmarshal(b, &v); err != nil { return err } diff --git a/mapslice_test.go b/mapslice_test.go index f451a62..8b1ee4e 100644 --- a/mapslice_test.go +++ b/mapslice_test.go @@ -7,10 +7,10 @@ import ( ) func TestMarshal(t *testing.T) { - ms := MapSlice{ - MapItem{Key: "abc", Value: 123}, - MapItem{Key: "def", Value: 456}, - MapItem{Key: "ghi", Value: 789}, + ms := MapSlice[int]{ + MapItem[int]{Key: "abc", Value: 123}, + MapItem[int]{Key: "def", Value: 456}, + MapItem[int]{Key: "ghi", Value: 789}, } b, err := json.Marshal(ms) @@ -27,18 +27,18 @@ func TestMarshal(t *testing.T) { } func TestMarshalError(t *testing.T) { - ms := MapSlice{ - MapItem{Key: "abc", Value: make(chan int)}, + ms := MapSlice[chan int]{ + MapItem[chan int]{Key: "abc", Value: make(chan int)}, } - e := "json: error calling MarshalJSON for type mapslice.MapSlice: json: unsupported type: chan int" + e := "json: error calling MarshalJSON for type mapslice.MapSlice[chan int]: json: unsupported type: chan int" if _, err := json.Marshal(ms); err != nil && e != err.Error() { t.Errorf("expected: %s\ngot: %v", e, err) } } func TestUnmarshal(t *testing.T) { - ms := MapSlice{} + ms := MapSlice[int]{} if err := json.Unmarshal([]byte("{\"abc\":123,\"def\":456,\"ghi\":789}"), &ms); err != nil { t.Fatal(err) }