| 1 | // Package fn provides generic utility functions for zero values, tuple |
| 2 | // selectors, must-helpers, and partial application. |
| 3 | package fn |
| 4 | |
| 5 | import "reflect" |
| 6 | |
| 7 | // Zero returns the zero value of type T. |
| 8 | func Zero[T any]() T { |
| 9 | var rv T |
| 10 | return rv |
| 11 | } |
| 12 | |
| 13 | // IsZero reports whether inp equals the zero value of its type. |
| 14 | func IsZero[T comparable](inp T) bool { |
| 15 | return inp == Zero[T]() |
| 16 | } |
| 17 | |
| 18 | // GetType returns the [reflect.Type] of type T without requiring an instance. |
| 19 | func GetType[T any]() reflect.Type { |
| 20 | return reflect.TypeOf(Zero[T]()) |
| 21 | } |
| 22 | |
| 23 | // FirstOf2 returns the first of two arguments, discarding the second. |
| 24 | // It is useful for inlining multi-return calls when only the first value is needed. |
| 25 | func FirstOf2[V1 any, V2 any](a V1, _ V2) V1 { |
| 26 | return a |
| 27 | } |
| 28 | |
| 29 | // SecondOf2 returns the second of two arguments, discarding the first. |
| 30 | func SecondOf2[V1 any, V2 any](_ V1, a V2) V2 { |
| 31 | return a |
| 32 | } |
| 33 | |
| 34 | // FirstOf3 returns the first of three arguments, discarding the rest. |
| 35 | func FirstOf3[V1 any, V2 any, V3 any](a V1, _ V2, _ V3) V1 { |
| 36 | return a |
| 37 | } |
| 38 | |
| 39 | // SecondOf3 returns the second of three arguments, discarding the rest. |
| 40 | func SecondOf3[V1 any, V2 any, V3 any](_ V1, a V2, _ V3) V2 { |
| 41 | return a |
| 42 | } |
| 43 | |
| 44 | // ThirdOf3 returns the third of three arguments, discarding the rest. |
| 45 | func ThirdOf3[V1 any, V2 any, V3 any](_ V1, _ V2, a V3) V3 { |
| 46 | return a |
| 47 | } |
| 48 | |
| 49 | // Must panics if err is non-nil. It is intended for wrapping calls that return |
| 50 | // only an error in contexts where failure is unexpected. |
| 51 | func Must(err error) { |
| 52 | if err != nil { |
| 53 | panic(err) |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | // Must1 returns v1 or panics if err is non-nil. |
| 58 | // It is intended for wrapping calls of the form func() (T, error). |
| 59 | func Must1[V1 any](v1 V1, err error) V1 { |
| 60 | if err != nil { |
| 61 | panic(err) |
| 62 | } |
| 63 | return v1 |
| 64 | } |
| 65 | |
| 66 | // Must2 returns (v1, v2) or panics if err is non-nil. |
| 67 | // It is intended for wrapping calls of the form func() (T1, T2, error). |
| 68 | func Must2[V1 any, V2 any](v1 V1, v2 V2, err error) (V1, V2) { |
| 69 | if err != nil { |
| 70 | panic(err) |
| 71 | } |
| 72 | return v1, v2 |
| 73 | } |
| 74 | |
| 75 | // Must3 returns (v1, v2, v3) or panics if err is non-nil. |
| 76 | // It is intended for wrapping calls of the form func() (T1, T2, T3, error). |
| 77 | func Must3[V1 any, V2 any, V3 any](v1 V1, v2 V2, v3 V3, err error) (V1, V2, V3) { |
| 78 | if err != nil { |
| 79 | panic(err) |
| 80 | } |
| 81 | return v1, v2, v3 |
| 82 | } |
| 83 | |
| 84 | // Curry1 partially applies f with v1, returning a zero-argument closure. |
| 85 | func Curry1[V1 any](f func(V1), v1 V1) func() { |
| 86 | return func() { f(v1) } |
| 87 | } |
| 88 | |