From cd0c0c2717fd0e569793db51817855b80dbafbad Mon Sep 17 00:00:00 2001 From: tbxark Date: Thu, 14 Nov 2024 15:02:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=85=83=E7=BB=84?= =?UTF-8?q?=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/utils/tuple/gen/gen.go | 102 ++++++ pkg/utils/tuple/setter.go | 43 +++ pkg/utils/tuple/setter_test.go | 38 +++ pkg/utils/tuple/tuple.go | 592 +++++++++++++++++++++++++++++++++ pkg/utils/tuple/tuple_test.go | 50 +++ 5 files changed, 825 insertions(+) create mode 100644 pkg/utils/tuple/gen/gen.go create mode 100644 pkg/utils/tuple/setter.go create mode 100644 pkg/utils/tuple/setter_test.go create mode 100644 pkg/utils/tuple/tuple.go create mode 100644 pkg/utils/tuple/tuple_test.go diff --git a/pkg/utils/tuple/gen/gen.go b/pkg/utils/tuple/gen/gen.go new file mode 100644 index 0000000..a2fd3d6 --- /dev/null +++ b/pkg/utils/tuple/gen/gen.go @@ -0,0 +1,102 @@ +package gen + +import ( + "fmt" + "io" + "text/template" +) + +type Field struct { + Name string + Type string +} + +type Desc struct { + Num int + Fields []Field +} + +const tupleTemplate = `// Package tuple Code generated by go generate; DO NOT EDIT. +package tuple + +import ( + "encoding/json" + "fmt" +) + +{{range .}} +// Of{{.Num}} represents a tuple of {{.Num}} elements +type Of{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}} any{{end}}] struct { + {{range .Fields}}{{.Name}} {{.Type}} + {{end}} +} + +// New{{.Num}} creates a new tuple of {{.Num}} elements +func New{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}} any{{end}}]({{range $i, $f := .Fields}}{{if $i}}, {{end}}{{lower .Name}} {{.Type}}{{end}}) Of{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}}{{end}}] { + return Of{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}}{{end}}]{ + {{range .Fields}}{{.Name}}: {{lower .Name}}, + {{end}} + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}}{{end}}]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{ {{range $i, $f := .Fields}}{{if $i}}, {{end}}t.{{.Name}}{{end}} }) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of{{.Num}}[{{range $i, $f := .Fields}}{{if $i}}, {{end}}{{.Type}}{{end}}]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < {{.Num}} { + return fmt.Errorf("expected array of length {{.Num}}, got %d", len(raw)) + } + + {{range $i, $f := .Fields}} + if err := json.Unmarshal(raw[{{$i}}], &t.{{.Name}}); err != nil { + return fmt.Errorf("failed to unmarshal {{lower .Name}} element: %w", err) + } + {{end}} + + return nil +} +{{end}} +` + +func Gen(writer io.Writer) { + fieldNames := []string{ + "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth", + } + typesNames := []string{ + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + } + var list []Desc + for i := 2; i <= 10; i++ { + row := Desc{Num: i} + for j := 0; j < i; j++ { + row.Fields = append(row.Fields, Field{ + Name: fieldNames[j], + Type: typesNames[j], + }) + } + list = append(list, row) + } + + tmpl, err := template.New("tuple").Funcs(template.FuncMap{ + "lower": func(s string) string { + return string(s[0]+32) + s[1:] + }, + }).Parse(tupleTemplate) + if err != nil { + fmt.Println("Error parsing template:", err) + return + } + + err = tmpl.Execute(writer, list) + if err != nil { + fmt.Println("Error executing template:", err) + } +} diff --git a/pkg/utils/tuple/setter.go b/pkg/utils/tuple/setter.go new file mode 100644 index 0000000..e8f51fe --- /dev/null +++ b/pkg/utils/tuple/setter.go @@ -0,0 +1,43 @@ +package tuple + +import ( + "fmt" + "reflect" +) + +func SetToStruct(tuple interface{}, dst interface{}, offset int) error { + tupleValue := reflect.ValueOf(tuple) + if tupleValue.Kind() == reflect.Ptr { + tupleValue = tupleValue.Elem() + } + if tupleValue.Kind() != reflect.Struct { + return fmt.Errorf("tuple must be a struct, got %v", tupleValue.Kind()) + } + dstValue := reflect.ValueOf(dst) + if dstValue.Kind() != reflect.Ptr { + return fmt.Errorf("destination must be a pointer, got %v", dstValue.Kind()) + } + dstValue = dstValue.Elem() + if dstValue.Kind() != reflect.Struct { + return fmt.Errorf("destination must be a pointer to struct, got pointer to %v", dstValue.Kind()) + } + tupleFields := tupleValue.NumField() + dstFields := dstValue.NumField() + for i := 0; i < tupleFields; i++ { + if i+offset < 0 || i+offset >= dstFields { + continue + } + tupleField := tupleValue.Field(i) + dstField := dstValue.Field(i + offset) + if !dstField.CanSet() { + return fmt.Errorf("field %d in destination struct is not settable", i) + } + if !tupleField.Type().AssignableTo(dstField.Type()) { + return fmt.Errorf("field %d type mismatch: cannot assign %v to %v", + i, tupleField.Type(), dstField.Type()) + } + dstField.Set(tupleField) + } + + return nil +} diff --git a/pkg/utils/tuple/setter_test.go b/pkg/utils/tuple/setter_test.go new file mode 100644 index 0000000..97d3e3c --- /dev/null +++ b/pkg/utils/tuple/setter_test.go @@ -0,0 +1,38 @@ +package tuple + +import "testing" + +func TestSetToStruct(t *testing.T) { + var test struct { + Key string + Value int + } + tuple := New2("hello", 42) + err := SetToStruct(&tuple, &test, 0) + if err != nil { + t.Fatal(err) + } + if test.Key != tuple.First { + t.Fatalf("expected %q, got %q", tuple.First, test.Key) + } + if test.Value != tuple.Second { + t.Fatalf("expected %d, got %d", tuple.Second, test.Value) + } + + var test2 struct { + hidden string + Key string + Value int + } + err = SetToStruct(&tuple, &test2, 1) + if err != nil { + t.Fatal(err) + } + if test2.Key != tuple.First { + t.Fatalf("expected %q, got %q", tuple.First, test2.Key) + } + if test2.Value != tuple.Second { + t.Fatalf("expected %d, got %d", tuple.Second, test2.Value) + } + +} diff --git a/pkg/utils/tuple/tuple.go b/pkg/utils/tuple/tuple.go new file mode 100644 index 0000000..038a994 --- /dev/null +++ b/pkg/utils/tuple/tuple.go @@ -0,0 +1,592 @@ +// Package tuple Code generated by go generate; DO NOT EDIT. +package tuple + +import ( + "encoding/json" + "fmt" +) + +// Of2 represents a tuple of 2 elements +type Of2[A any, B any] struct { + First A + Second B +} + +// New2 creates a new tuple of 2 elements +func New2[A any, B any](first A, second B) Of2[A, B] { + return Of2[A, B]{ + First: first, + Second: second, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of2[A, B]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of2[A, B]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 2 { + return fmt.Errorf("expected array of length 2, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + return nil +} + +// Of3 represents a tuple of 3 elements +type Of3[A any, B any, C any] struct { + First A + Second B + Third C +} + +// New3 creates a new tuple of 3 elements +func New3[A any, B any, C any](first A, second B, third C) Of3[A, B, C] { + return Of3[A, B, C]{ + First: first, + Second: second, + Third: third, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of3[A, B, C]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of3[A, B, C]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 3 { + return fmt.Errorf("expected array of length 3, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + return nil +} + +// Of4 represents a tuple of 4 elements +type Of4[A any, B any, C any, D any] struct { + First A + Second B + Third C + Fourth D +} + +// New4 creates a new tuple of 4 elements +func New4[A any, B any, C any, D any](first A, second B, third C, fourth D) Of4[A, B, C, D] { + return Of4[A, B, C, D]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of4[A, B, C, D]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of4[A, B, C, D]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 4 { + return fmt.Errorf("expected array of length 4, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + return nil +} + +// Of5 represents a tuple of 5 elements +type Of5[A any, B any, C any, D any, E any] struct { + First A + Second B + Third C + Fourth D + Fifth E +} + +// New5 creates a new tuple of 5 elements +func New5[A any, B any, C any, D any, E any](first A, second B, third C, fourth D, fifth E) Of5[A, B, C, D, E] { + return Of5[A, B, C, D, E]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of5[A, B, C, D, E]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of5[A, B, C, D, E]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 5 { + return fmt.Errorf("expected array of length 5, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + return nil +} + +// Of6 represents a tuple of 6 elements +type Of6[A any, B any, C any, D any, E any, F any] struct { + First A + Second B + Third C + Fourth D + Fifth E + Sixth F +} + +// New6 creates a new tuple of 6 elements +func New6[A any, B any, C any, D any, E any, F any](first A, second B, third C, fourth D, fifth E, sixth F) Of6[A, B, C, D, E, F] { + return Of6[A, B, C, D, E, F]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + Sixth: sixth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of6[A, B, C, D, E, F]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth, t.Sixth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of6[A, B, C, D, E, F]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 6 { + return fmt.Errorf("expected array of length 6, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + if err := json.Unmarshal(raw[5], &t.Sixth); err != nil { + return fmt.Errorf("failed to unmarshal sixth element: %w", err) + } + + return nil +} + +// Of7 represents a tuple of 7 elements +type Of7[A any, B any, C any, D any, E any, F any, G any] struct { + First A + Second B + Third C + Fourth D + Fifth E + Sixth F + Seventh G +} + +// New7 creates a new tuple of 7 elements +func New7[A any, B any, C any, D any, E any, F any, G any](first A, second B, third C, fourth D, fifth E, sixth F, seventh G) Of7[A, B, C, D, E, F, G] { + return Of7[A, B, C, D, E, F, G]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + Sixth: sixth, + Seventh: seventh, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of7[A, B, C, D, E, F, G]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth, t.Sixth, t.Seventh}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of7[A, B, C, D, E, F, G]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 7 { + return fmt.Errorf("expected array of length 7, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + if err := json.Unmarshal(raw[5], &t.Sixth); err != nil { + return fmt.Errorf("failed to unmarshal sixth element: %w", err) + } + + if err := json.Unmarshal(raw[6], &t.Seventh); err != nil { + return fmt.Errorf("failed to unmarshal seventh element: %w", err) + } + + return nil +} + +// Of8 represents a tuple of 8 elements +type Of8[A any, B any, C any, D any, E any, F any, G any, H any] struct { + First A + Second B + Third C + Fourth D + Fifth E + Sixth F + Seventh G + Eighth H +} + +// New8 creates a new tuple of 8 elements +func New8[A any, B any, C any, D any, E any, F any, G any, H any](first A, second B, third C, fourth D, fifth E, sixth F, seventh G, eighth H) Of8[A, B, C, D, E, F, G, H] { + return Of8[A, B, C, D, E, F, G, H]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + Sixth: sixth, + Seventh: seventh, + Eighth: eighth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of8[A, B, C, D, E, F, G, H]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth, t.Sixth, t.Seventh, t.Eighth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of8[A, B, C, D, E, F, G, H]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 8 { + return fmt.Errorf("expected array of length 8, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + if err := json.Unmarshal(raw[5], &t.Sixth); err != nil { + return fmt.Errorf("failed to unmarshal sixth element: %w", err) + } + + if err := json.Unmarshal(raw[6], &t.Seventh); err != nil { + return fmt.Errorf("failed to unmarshal seventh element: %w", err) + } + + if err := json.Unmarshal(raw[7], &t.Eighth); err != nil { + return fmt.Errorf("failed to unmarshal eighth element: %w", err) + } + + return nil +} + +// Of9 represents a tuple of 9 elements +type Of9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struct { + First A + Second B + Third C + Fourth D + Fifth E + Sixth F + Seventh G + Eighth H + Ninth I +} + +// New9 creates a new tuple of 9 elements +func New9[A any, B any, C any, D any, E any, F any, G any, H any, I any](first A, second B, third C, fourth D, fifth E, sixth F, seventh G, eighth H, ninth I) Of9[A, B, C, D, E, F, G, H, I] { + return Of9[A, B, C, D, E, F, G, H, I]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + Sixth: sixth, + Seventh: seventh, + Eighth: eighth, + Ninth: ninth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of9[A, B, C, D, E, F, G, H, I]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth, t.Sixth, t.Seventh, t.Eighth, t.Ninth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of9[A, B, C, D, E, F, G, H, I]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 9 { + return fmt.Errorf("expected array of length 9, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + if err := json.Unmarshal(raw[5], &t.Sixth); err != nil { + return fmt.Errorf("failed to unmarshal sixth element: %w", err) + } + + if err := json.Unmarshal(raw[6], &t.Seventh); err != nil { + return fmt.Errorf("failed to unmarshal seventh element: %w", err) + } + + if err := json.Unmarshal(raw[7], &t.Eighth); err != nil { + return fmt.Errorf("failed to unmarshal eighth element: %w", err) + } + + if err := json.Unmarshal(raw[8], &t.Ninth); err != nil { + return fmt.Errorf("failed to unmarshal ninth element: %w", err) + } + + return nil +} + +// Of10 represents a tuple of 10 elements +type Of10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any] struct { + First A + Second B + Third C + Fourth D + Fifth E + Sixth F + Seventh G + Eighth H + Ninth I + Tenth J +} + +// New10 creates a new tuple of 10 elements +func New10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](first A, second B, third C, fourth D, fifth E, sixth F, seventh G, eighth H, ninth I, tenth J) Of10[A, B, C, D, E, F, G, H, I, J] { + return Of10[A, B, C, D, E, F, G, H, I, J]{ + First: first, + Second: second, + Third: third, + Fourth: fourth, + Fifth: fifth, + Sixth: sixth, + Seventh: seventh, + Eighth: eighth, + Ninth: ninth, + Tenth: tenth, + } +} + +// MarshalJSON implements json.Marshaler interface +func (t *Of10[A, B, C, D, E, F, G, H, I, J]) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{t.First, t.Second, t.Third, t.Fourth, t.Fifth, t.Sixth, t.Seventh, t.Eighth, t.Ninth, t.Tenth}) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (t *Of10[A, B, C, D, E, F, G, H, I, J]) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + if err := json.Unmarshal(data, &raw); err != nil { + return fmt.Errorf("failed to unmarshal array: %w", err) + } + + if len(raw) < 10 { + return fmt.Errorf("expected array of length 10, got %d", len(raw)) + } + + if err := json.Unmarshal(raw[0], &t.First); err != nil { + return fmt.Errorf("failed to unmarshal first element: %w", err) + } + + if err := json.Unmarshal(raw[1], &t.Second); err != nil { + return fmt.Errorf("failed to unmarshal second element: %w", err) + } + + if err := json.Unmarshal(raw[2], &t.Third); err != nil { + return fmt.Errorf("failed to unmarshal third element: %w", err) + } + + if err := json.Unmarshal(raw[3], &t.Fourth); err != nil { + return fmt.Errorf("failed to unmarshal fourth element: %w", err) + } + + if err := json.Unmarshal(raw[4], &t.Fifth); err != nil { + return fmt.Errorf("failed to unmarshal fifth element: %w", err) + } + + if err := json.Unmarshal(raw[5], &t.Sixth); err != nil { + return fmt.Errorf("failed to unmarshal sixth element: %w", err) + } + + if err := json.Unmarshal(raw[6], &t.Seventh); err != nil { + return fmt.Errorf("failed to unmarshal seventh element: %w", err) + } + + if err := json.Unmarshal(raw[7], &t.Eighth); err != nil { + return fmt.Errorf("failed to unmarshal eighth element: %w", err) + } + + if err := json.Unmarshal(raw[8], &t.Ninth); err != nil { + return fmt.Errorf("failed to unmarshal ninth element: %w", err) + } + + if err := json.Unmarshal(raw[9], &t.Tenth); err != nil { + return fmt.Errorf("failed to unmarshal tenth element: %w", err) + } + + return nil +} diff --git a/pkg/utils/tuple/tuple_test.go b/pkg/utils/tuple/tuple_test.go new file mode 100644 index 0000000..4eb5b7e --- /dev/null +++ b/pkg/utils/tuple/tuple_test.go @@ -0,0 +1,50 @@ +package tuple + +import ( + "testing" +) + +//func Test_GenTuple(t *testing.T) { +// gen.Gen(os.Stdout) +//} + +func TestOf2_UnmarshalJSON(t *testing.T) { + pair := New2("hello", 42) + data, err := pair.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var pair2 Of2[string, int] + err = pair2.UnmarshalJSON(data) + if err != nil { + t.Fatal(err) + } + if pair.First != pair2.First { + t.Fatalf("expected %q, got %q", pair.First, pair2.First) + } + if pair.Second != pair2.Second { + t.Fatalf("expected %d, got %d", pair.Second, pair2.Second) + } +} + +func TestOf3_UnmarshalJSON(t *testing.T) { + pair := New3("hello", 42, "world") + data, err := pair.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var pair2 Of3[string, int, string] + err = pair2.UnmarshalJSON(data) + if err != nil { + t.Fatal(err) + } + if pair.First != pair2.First { + t.Fatalf("expected %q, got %q", pair.First, pair2.First) + } + if pair.Second != pair2.Second { + t.Fatalf("expected %d, got %d", pair.Second, pair2.Second) + } + if pair.Third != pair2.Third { + t.Fatalf("expected %q, got %q", pair.Third, pair2.Third) + } +}