diff --git a/tuple/tuple.go b/tuple/tuple.go new file mode 100644 index 0000000..f8450a8 --- /dev/null +++ b/tuple/tuple.go @@ -0,0 +1,203 @@ +// Copyright 2023 dudaodong@gmail.com. All rights reserved. +// Use of this source code is governed by MIT license + +// Package tuple implements tuple data type and some operations on it. +package tuple + +// Tuple2 represents a 2 elemnets tuple +type Tuple2[A any, B any] struct { + FieldA A + FieldB B +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple2[A, B]) Unbox() (A, B) { + return t.FieldA, t.FieldB +} + +// NewTuple2 creates a 2 elemnets tuple from a list of values. +// Play: todo +func NewTuple2[A any, B any](a A, b B) Tuple2[A, B] { + return Tuple2[A, B]{FieldA: a, FieldB: b} +} + +// Tuple3 represents a 3 elemnets tuple +type Tuple3[A any, B any, C any] struct { + FieldA A + FieldB B + FieldC C +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple3[A, B, C]) Unbox() (A, B, C) { + return t.FieldA, t.FieldB, t.FieldC +} + +// NewTuple3 creates a 3 elemnets tuple from a list of values. +// Play: todo +func NewTuple3[A any, B any, C any](a A, b B, c C) Tuple3[A, B, C] { + return Tuple3[A, B, C]{FieldA: a, FieldB: b, FieldC: c} +} + +// Tuple4 represents a 4 elemnets tuple +type Tuple4[A any, B any, C any, D any] struct { + FieldA A + FieldB B + FieldC C + FieldD D +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple4[A, B, C, D]) Unbox() (A, B, C, D) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD +} + +// NewTuple4 creates a 4 elemnets tuple from a list of values. +// Play: todo +func NewTuple4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] { + return Tuple4[A, B, C, D]{FieldA: a, FieldB: b, FieldC: c, FieldD: d} +} + +// Tuple5 represents a 5 elemnets tuple +type Tuple5[A any, B any, C any, D any, E any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple5[A, B, C, D, E]) Unbox() (A, B, C, D, E) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE +} + +// NewTuple5 creates a 5 elemnets tuple from a list of values. +// Play: todo +func NewTuple5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] { + return Tuple5[A, B, C, D, E]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e} +} + +// Tuple6 represents a 6 elemnets tuple +type Tuple6[A any, B any, C any, D any, E any, F any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple6[A, B, C, D, E, F]) Unbox() (A, B, C, D, E, F) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF +} + +// NewTuple6 creates a 6 elemnets tuple from a list of values. +// Play: todo +func NewTuple6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] { + return Tuple6[A, B, C, D, E, F]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f} +} + +// Tuple7 represents a 7 elemnets tuple +type Tuple7[A any, B any, C any, D any, E any, F any, G any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple7[A, B, C, D, E, F, G]) Unbox() (A, B, C, D, E, F, G) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG +} + +// NewTuple7 creates a 7 elemnets tuple from a list of values. +// Play: todo +func NewTuple7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] { + return Tuple7[A, B, C, D, E, F, G]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g} +} + +// Tuple8 represents a 8 elemnets tuple +type Tuple8[A any, B any, C any, D any, E any, F any, G any, H any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple8[A, B, C, D, E, F, G, H]) Unbox() (A, B, C, D, E, F, G, H) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH +} + +// NewTuple8 creates a 8 elemnets tuple from a list of values. +// Play: todo +func NewTuple8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] { + return Tuple8[A, B, C, D, E, F, G, H]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h} +} + +// Tuple9 represents a 9 elemnets tuple +type Tuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unbox() (A, B, C, D, E, F, G, H, I) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI +} + +// NewTuple9 creates a 9 elemnets tuple from a list of values. +// Play: todo +func NewTuple9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] { + return Tuple9[A, B, C, D, E, F, G, H, I]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i} +} + +// Tuple10 represents a 10 elemnets tuple +type Tuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any] struct { + FieldA A + FieldB B + FieldC C + FieldD D + FieldE E + FieldF F + FieldG G + FieldH H + FieldI I + FieldJ J +} + +// Unbox returns values in tuple. +// Play: todo +func (t Tuple10[A, B, C, D, E, F, G, H, I, J]) Unbox() (A, B, C, D, E, F, G, H, I, J) { + return t.FieldA, t.FieldB, t.FieldC, t.FieldD, t.FieldE, t.FieldF, t.FieldG, t.FieldH, t.FieldI, t.FieldJ +} + +// NewTuple10 creates a 10 elemnets tuple from a list of values. +// Play: todo +func NewTuple10[A any, B any, C any, D any, E any, F any, G any, H any, I any, J any](a A, b B, c C, d D, e E, f F, g G, h H, i I, j J) Tuple10[A, B, C, D, E, F, G, H, I, J] { + return Tuple10[A, B, C, D, E, F, G, H, I, J]{FieldA: a, FieldB: b, FieldC: c, FieldD: d, FieldE: e, FieldF: f, FieldG: g, FieldH: h, FieldI: i, FieldJ: j} +} diff --git a/tuple/tuple_test.go b/tuple/tuple_test.go new file mode 100644 index 0000000..e31f730 --- /dev/null +++ b/tuple/tuple_test.go @@ -0,0 +1,129 @@ +// Copyright 2023 dudaodong@gmail.com. All rights reserved. +// Use of this source code is governed by MIT license + +// Package tuple implements tuple data type and some operations on it. +package tuple + +import ( + "testing" + + "github.com/duke-git/lancet/v2/internal" +) + +func TestTuples(t *testing.T) { + assert := internal.NewAssert(t, "TestTuples") + + type foo struct { + A string + } + + t2 := NewTuple2[int, float64](1, 0.1) + t3 := NewTuple3[int, float64, string](1, 0.1, "a") + t4 := NewTuple4[int, float64, string, bool](1, 0.1, "a", true) + t5 := NewTuple5[int, float64, string, bool, int64](1, 0.1, "a", true, 2) + t6 := NewTuple6[int, float64, string, bool, int64, float32](1, 0.1, "a", true, 2, 2.2) + t7 := NewTuple7[int, float64, string, bool, int64, float32, string](1, 0.1, "a", true, 2, 2.2, "b") + t8 := NewTuple8[int, float64, string, bool, int64, float32, string, string](1, 0.1, "a", true, 2, 2.2, "b", "c") + t9 := NewTuple9[int, float64, string, bool, int64, float32, string, string, map[string]int](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + t10 := NewTuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + + assert.Equal(t2, Tuple2[int, float64]{FieldA: 1, FieldB: 0.1}) + assert.Equal(t3, Tuple3[int, float64, string]{FieldA: 1, FieldB: 0.1, FieldC: "a"}) + assert.Equal(t4, Tuple4[int, float64, string, bool]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true}) + assert.Equal(t5, Tuple5[int, float64, string, bool, int64]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2}) + assert.Equal(t6, Tuple6[int, float64, string, bool, int64, float32]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2}) + assert.Equal(t7, Tuple7[int, float64, string, bool, int64, float32, string]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b"}) + assert.Equal(t8, Tuple8[int, float64, string, bool, int64, float32, string, string]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c"}) + assert.Equal(t9, Tuple9[int, float64, string, bool, int64, float32, string, string, map[string]int]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: map[string]int{"a": 1}}) + assert.Equal(t10, Tuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo]{FieldA: 1, FieldB: 0.1, FieldC: "a", FieldD: true, FieldE: 2, FieldF: 2.2, FieldG: "b", FieldH: "c", FieldI: map[string]int{"a": 1}, FieldJ: foo{A: "a"}}) +} + +func TestTuple_Unbox(t *testing.T) { + assert := internal.NewAssert(t, "TestTuple_Unbox") + + type foo struct { + A string + } + + t2 := NewTuple2[int, float64](1, 0.1) + v1, v2 := t2.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + + t3 := NewTuple3[int, float64, string](1, 0.1, "a") + v1, v2, v3 := t3.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + + t4 := NewTuple4[int, float64, string, bool](1, 0.1, "a", true) + v1, v2, v3, v4 := t4.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + + t5 := NewTuple5[int, float64, string, bool, int64](1, 0.1, "a", true, 2) + v1, v2, v3, v4, v5 := t5.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + + t6 := NewTuple6[int, float64, string, bool, int64, float32](1, 0.1, "a", true, 2, 2.2) + v1, v2, v3, v4, v5, v6 := t6.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + assert.Equal(float32(2.2), v6) + + t7 := NewTuple7[int, float64, string, bool, int64, float32, string](1, 0.1, "a", true, 2, 2.2, "b") + v1, v2, v3, v4, v5, v6, v7 := t7.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + assert.Equal(float32(2.2), v6) + assert.Equal("b", v7) + + t8 := NewTuple8[int, float64, string, bool, int64, float32, string, string](1, 0.1, "a", true, 2, 2.2, "b", "c") + v1, v2, v3, v4, v5, v6, v7, v8 := t8.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + assert.Equal(float32(2.2), v6) + assert.Equal("b", v7) + assert.Equal("c", v8) + + t9 := NewTuple9[int, float64, string, bool, int64, float32, string, string, map[string]int](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}) + v1, v2, v3, v4, v5, v6, v7, v8, v9 := t9.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + assert.Equal(float32(2.2), v6) + assert.Equal("b", v7) + assert.Equal("c", v8) + assert.Equal(map[string]int{"a": 1}, v9) + + t10 := NewTuple10[int, float64, string, bool, int64, float32, string, string, map[string]int, foo](1, 0.1, "a", true, 2, 2.2, "b", "c", map[string]int{"a": 1}, foo{A: "a"}) + v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 := t10.Unbox() + assert.Equal(1, v1) + assert.Equal(0.1, v2) + assert.Equal("a", v3) + assert.Equal(true, v4) + assert.Equal(int64(2), v5) + assert.Equal(float32(2.2), v6) + assert.Equal("b", v7) + assert.Equal("c", v8) + assert.Equal(map[string]int{"a": 1}, v9) + assert.Equal(foo{A: "a"}, v10) + +}