package mo import "fmt" const ( either4ArgId1 = iota either4ArgId2 either4ArgId3 either4ArgId4 ) var ( errEither4InvalidArgumentId = fmt.Errorf("either4 argument should be between 1 and 4") errEither4MissingArg1 = fmt.Errorf("either4 doesn't contain expected argument 1") errEither4MissingArg2 = fmt.Errorf("either4 doesn't contain expected argument 2") errEither4MissingArg3 = fmt.Errorf("either4 doesn't contain expected argument 3") errEither4MissingArg4 = fmt.Errorf("either4 doesn't contain expected argument 4") ) // NewEither4Arg1 builds the first argument of the Either4 struct. func NewEither4Arg1[T1 any, T2 any, T3 any, T4 any](value T1) Either4[T1, T2, T3, T4] { return Either4[T1, T2, T3, T4]{ argId: either4ArgId1, arg1: value, } } // NewEither4Arg2 builds the second argument of the Either4 struct. func NewEither4Arg2[T1 any, T2 any, T3 any, T4 any](value T2) Either4[T1, T2, T3, T4] { return Either4[T1, T2, T3, T4]{ argId: either4ArgId2, arg2: value, } } // NewEither4Arg3 builds the third argument of the Either4 struct. func NewEither4Arg3[T1 any, T2 any, T3 any, T4 any](value T3) Either4[T1, T2, T3, T4] { return Either4[T1, T2, T3, T4]{ argId: either4ArgId3, arg3: value, } } // NewEither4Arg4 builds the fourth argument of the Either4 struct. func NewEither4Arg4[T1 any, T2 any, T3 any, T4 any](value T4) Either4[T1, T2, T3, T4] { return Either4[T1, T2, T3, T4]{ argId: either4ArgId4, arg4: value, } } // Either4 respresents a value of 4 possible types. // An instance of Either4 is an instance of either T1, T2, T3 or T4. type Either4[T1 any, T2 any, T3 any, T4 any] struct { argId int8 arg1 T1 arg2 T2 arg3 T3 arg4 T4 } // IsArg1 returns true if Either4 uses the first argument. func (e Either4[T1, T2, T3, T4]) IsArg1() bool { return e.argId == either4ArgId1 } // IsArg2 returns true if Either4 uses the second argument. func (e Either4[T1, T2, T3, T4]) IsArg2() bool { return e.argId == either4ArgId2 } // IsArg3 returns true if Either4 uses the third argument. func (e Either4[T1, T2, T3, T4]) IsArg3() bool { return e.argId == either4ArgId3 } // IsArg4 returns true if Either4 uses the fourth argument. func (e Either4[T1, T2, T3, T4]) IsArg4() bool { return e.argId == either4ArgId4 } // Arg1 returns the first argument of a Either4 struct. func (e Either4[T1, T2, T3, T4]) Arg1() (T1, bool) { if e.IsArg1() { return e.arg1, true } return empty[T1](), false } // Arg2 returns the second argument of a Either4 struct. func (e Either4[T1, T2, T3, T4]) Arg2() (T2, bool) { if e.IsArg2() { return e.arg2, true } return empty[T2](), false } // Arg3 returns the third argument of a Either4 struct. func (e Either4[T1, T2, T3, T4]) Arg3() (T3, bool) { if e.IsArg3() { return e.arg3, true } return empty[T3](), false } // Arg4 returns the fourth argument of a Either4 struct. func (e Either4[T1, T2, T3, T4]) Arg4() (T4, bool) { if e.IsArg4() { return e.arg4, true } return empty[T4](), false } // MustArg1 returns the first argument of a Either4 struct or panics. func (e Either4[T1, T2, T3, T4]) MustArg1() T1 { if !e.IsArg1() { panic(errEither4MissingArg1) } return e.arg1 } // MustArg2 returns the second argument of a Either4 struct or panics. func (e Either4[T1, T2, T3, T4]) MustArg2() T2 { if !e.IsArg2() { panic(errEither4MissingArg2) } return e.arg2 } // MustArg3 returns the third argument of a Either4 struct or panics. func (e Either4[T1, T2, T3, T4]) MustArg3() T3 { if !e.IsArg3() { panic(errEither4MissingArg3) } return e.arg3 } // MustArg4 returns the fourth argument of a Either4 struct or panics. func (e Either4[T1, T2, T3, T4]) MustArg4() T4 { if !e.IsArg4() { panic(errEither4MissingArg4) } return e.arg4 } // Unpack returns all values func (e Either4[T1, T2, T3, T4]) Unpack() (T1, T2, T3, T4) { return e.arg1, e.arg2, e.arg3, e.arg4 } // Arg1OrElse returns the first argument of a Either4 struct or fallback. func (e Either4[T1, T2, T3, T4]) Arg1OrElse(fallback T1) T1 { if e.IsArg1() { return e.arg1 } return fallback } // Arg2OrElse returns the second argument of a Either4 struct or fallback. func (e Either4[T1, T2, T3, T4]) Arg2OrElse(fallback T2) T2 { if e.IsArg2() { return e.arg2 } return fallback } // Arg3OrElse returns the third argument of a Either4 struct or fallback. func (e Either4[T1, T2, T3, T4]) Arg3OrElse(fallback T3) T3 { if e.IsArg3() { return e.arg3 } return fallback } // Arg4OrElse returns the fourth argument of a Either4 struct or fallback. func (e Either4[T1, T2, T3, T4]) Arg4OrElse(fallback T4) T4 { if e.IsArg4() { return e.arg4 } return fallback } // Arg1OrEmpty returns the first argument of a Either4 struct or empty value. func (e Either4[T1, T2, T3, T4]) Arg1OrEmpty() T1 { if e.IsArg1() { return e.arg1 } return empty[T1]() } // Arg2OrEmpty returns the second argument of a Either4 struct or empty value. func (e Either4[T1, T2, T3, T4]) Arg2OrEmpty() T2 { if e.IsArg2() { return e.arg2 } return empty[T2]() } // Arg3OrEmpty returns the third argument of a Either4 struct or empty value. func (e Either4[T1, T2, T3, T4]) Arg3OrEmpty() T3 { if e.IsArg3() { return e.arg3 } return empty[T3]() } // Arg4OrEmpty returns the fourth argument of a Either4 struct or empty value. func (e Either4[T1, T2, T3, T4]) Arg4OrEmpty() T4 { if e.IsArg4() { return e.arg4 } return empty[T4]() } // ForEach executes the given side-effecting function, depending of the argument set. func (e Either4[T1, T2, T3, T4]) ForEach(arg1Cb func(T1), arg2Cb func(T2), arg3Cb func(T3), arg4Cb func(T4)) { switch e.argId { case either4ArgId1: arg1Cb(e.arg1) case either4ArgId2: arg2Cb(e.arg2) case either4ArgId3: arg3Cb(e.arg3) case either4ArgId4: arg4Cb(e.arg4) } } // Match executes the given function, depending of the argument set, and returns result. func (e Either4[T1, T2, T3, T4]) Match( onArg1 func(T1) Either4[T1, T2, T3, T4], onArg2 func(T2) Either4[T1, T2, T3, T4], onArg3 func(T3) Either4[T1, T2, T3, T4], onArg4 func(T4) Either4[T1, T2, T3, T4]) Either4[T1, T2, T3, T4] { switch e.argId { case either4ArgId1: return onArg1(e.arg1) case either4ArgId2: return onArg2(e.arg2) case either4ArgId3: return onArg3(e.arg3) case either4ArgId4: return onArg4(e.arg4) } panic(errEither4InvalidArgumentId) } // MapArg1 executes the given function, if Either4 use the first argument, and returns result. func (e Either4[T1, T2, T3, T4]) MapArg1(mapper func(T1) Either4[T1, T2, T3, T4]) Either4[T1, T2, T3, T4] { if e.IsArg1() { return mapper(e.arg1) } return e } // MapArg2 executes the given function, if Either4 use the second argument, and returns result. func (e Either4[T1, T2, T3, T4]) MapArg2(mapper func(T2) Either4[T1, T2, T3, T4]) Either4[T1, T2, T3, T4] { if e.IsArg2() { return mapper(e.arg2) } return e } // MapArg3 executes the given function, if Either4 use the third argument, and returns result. func (e Either4[T1, T2, T3, T4]) MapArg3(mapper func(T3) Either4[T1, T2, T3, T4]) Either4[T1, T2, T3, T4] { if e.IsArg3() { return mapper(e.arg3) } return e } // MapArg4 executes the given function, if Either4 use the fourth argument, and returns result. func (e Either4[T1, T2, T3, T4]) MapArg4(mapper func(T4) Either4[T1, T2, T3, T4]) Either4[T1, T2, T3, T4] { if e.IsArg4() { return mapper(e.arg4) } return e }