From 8b99c470d808751b4e681d56d7c2546d0925f2d7 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 28 Mar 2026 02:10:40 +0100 Subject: [PATCH] feat: tipo suma Result[T] con Ok y Err Primer tipo del registry: Result generico inspirado en Rust. Tipo suma con dos variantes: Ok(T) y Err(error). Metodos: IsOk, IsErr, Unwrap, UnwrapErr, UnwrapOr. Incluye implementacion, documentacion .md y 4 tests. Co-Authored-By: Claude Opus 4.6 (1M context) --- types/core/.gitkeep | 0 types/core/result.go | 52 ++++++++++++++++++++++++++++++++++++++ types/core/result.md | 21 ++++++++++++++++ types/core/result_test.go | 53 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) delete mode 100644 types/core/.gitkeep create mode 100644 types/core/result.go create mode 100644 types/core/result.md create mode 100644 types/core/result_test.go diff --git a/types/core/.gitkeep b/types/core/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/types/core/result.go b/types/core/result.go new file mode 100644 index 00000000..d79ae6d7 --- /dev/null +++ b/types/core/result.go @@ -0,0 +1,52 @@ +package core + +// Result is a sum type representing either a successful value or an error. +// Exactly one of Ok or Err is non-nil at any time. +type Result[T any] struct { + ok *T + err error +} + +// Ok creates a successful Result. +func Ok[T any](v T) Result[T] { + return Result[T]{ok: &v} +} + +// Err creates a failed Result. +func Err[T any](err error) Result[T] { + return Result[T]{err: err} +} + +// IsOk returns true if the Result contains a value. +func (r Result[T]) IsOk() bool { + return r.ok != nil +} + +// IsErr returns true if the Result contains an error. +func (r Result[T]) IsErr() bool { + return r.err != nil +} + +// Unwrap returns the value or panics if the Result is an error. +func (r Result[T]) Unwrap() T { + if r.ok == nil { + panic("called Unwrap on an Err Result") + } + return *r.ok +} + +// UnwrapErr returns the error or panics if the Result is Ok. +func (r Result[T]) UnwrapErr() error { + if r.err == nil { + panic("called UnwrapErr on an Ok Result") + } + return r.err +} + +// UnwrapOr returns the value or a default if the Result is an error. +func (r Result[T]) UnwrapOr(def T) T { + if r.ok != nil { + return *r.ok + } + return def +} diff --git a/types/core/result.md b/types/core/result.md new file mode 100644 index 00000000..b3b455db --- /dev/null +++ b/types/core/result.md @@ -0,0 +1,21 @@ +--- +name: result +lang: go +domain: core +version: "1.0.0" +algebraic: sum +definition: | + type Result[T any] struct { + ok *T + err error + } +description: "Tipo suma generico que representa exito (Ok) o fallo (Err). Permite componer operaciones que pueden fallar sin recurrir a multiples returns (T, error)." +tags: [result, sum, error-handling, functional, generic] +uses_types: [] +file_path: "types/core/result.go" +--- + +## Notas + +Tipo suma con dos variantes: Ok(T) y Err(error). Inspirado en Result de Rust. +Util para encadenar operaciones y evitar el patron `if err != nil` repetitivo. diff --git a/types/core/result_test.go b/types/core/result_test.go new file mode 100644 index 00000000..2674fa50 --- /dev/null +++ b/types/core/result_test.go @@ -0,0 +1,53 @@ +package core + +import ( + "errors" + "testing" +) + +func TestResultOk(t *testing.T) { + r := Ok(42) + if !r.IsOk() { + t.Error("expected IsOk") + } + if r.IsErr() { + t.Error("expected not IsErr") + } + if r.Unwrap() != 42 { + t.Errorf("got %d, want 42", r.Unwrap()) + } +} + +func TestResultErr(t *testing.T) { + r := Err[int](errors.New("fail")) + if r.IsOk() { + t.Error("expected not IsOk") + } + if !r.IsErr() { + t.Error("expected IsErr") + } + if r.UnwrapErr().Error() != "fail" { + t.Errorf("got %v", r.UnwrapErr()) + } +} + +func TestUnwrapOr(t *testing.T) { + ok := Ok(10) + if ok.UnwrapOr(0) != 10 { + t.Error("UnwrapOr on Ok should return value") + } + + err := Err[int](errors.New("fail")) + if err.UnwrapOr(99) != 99 { + t.Error("UnwrapOr on Err should return default") + } +} + +func TestUnwrapPanics(t *testing.T) { + defer func() { + if recover() == nil { + t.Error("Unwrap on Err should panic") + } + }() + Err[int](errors.New("fail")).Unwrap() +}