// Package result provides a generic Expect[T] type for happy-path-oriented code. // // # Purpose // // result is a convenience tool for removing error-threading clutter from // application logic. Instead of propagating (value, error) pairs through every // frame, functions return Expect[T] and the caller unwraps at the boundary. // // # Layering rule // // Reusable library code (packages under pkg/) must only *return* Expect[T] — // it must never call .Expect(), .Must(), or .Expectf() itself. Those methods // exit the current goroutine via runtime.Goexit and are only safe inside a // goroutine controlled by [Go] or [Run]. Calling them in a library takes // control away from the caller and makes the package non-composable. // // The right split: // // - pkg/ functions: return Expect[T] or Expect[Nothing] — let the caller decide. // - Application code (cmd/, HTTP handlers, …): chain .Expect() calls freely, // protected by a defer result.Catch(&err) or a result.Run wrapper. // // # Intended pattern // // 1. Deep call stacks write for the happy path, using [Expect.Expect] or // [Expect.Expectf] to unwrap values — exiting the current goroutine via // runtime.Goexit on unexpected errors rather than threading error returns // through every frame. // 2. The entry point wraps the work with [Go] or [Run], which spawn the work // in a goroutine and collect any failure as a normal Go error. // // Stack traces are captured at the failure site and can be retrieved from the // collected error via [StackTrace]. // // # Constructors // // Use [Ok] to wrap a success value, [Fail] to wrap an error, and [Of] to // bridge existing (value, error) return signatures: // // data := result.Of(os.ReadFile("cfg.json")).Expect("read config") // // # Boundary pattern // // func run() error { // return result.Run(func() { // port := parsePort(cfg.Port).Expect("load config port") // _ = port // happy path continues … // }) // } // // [Go] is the typed variant — it returns Expect[T] when the closure produces // a value. [Run] is a convenience wrapper for closures that return nothing. // // Genuine runtime panics (nil-pointer dereferences, index out of bounds, etc.) // are not recovered — they still crash the program, as they should. package result