either

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package either represents a value ether L or R.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equal

func Equal[L, R comparable](l, r Either[L, R]) bool

Equal tests equality of l and r then returns true if they are equal, false otherwise.

func EqualEqualer

func EqualEqualer[L interface{ Equal(l L) bool }, R interface{ Equal(r R) bool }](l, r Either[L, R]) bool

EqualEqualer tests equality of l and r by calling the Equal method implemented on their held values.

func Transpose

func Transpose[T any](r Result[opt.Option[T]]) opt.Option[Result[T]]

Transpose converts a Result[opt.Option[T]] into an opt.Option[Result[T]]. An ok wrapping none maps to none. An ok wrapping some maps to some wrapping ok, and an err maps to some wrapping err.

func TransposeLeft

func TransposeLeft[L, R any](e Either[opt.Option[L], R]) opt.Option[Either[L, R]]

TransposeLeft converts an Either[opt.Option[L], R] into an opt.Option[Either[L, R]]. A left none maps to none. A left some maps to some wrapping left, and a right maps to some wrapping right.

func TransposeRight

func TransposeRight[L, R any](e Either[L, opt.Option[R]]) opt.Option[Either[L, R]]

TransposeRight converts an Either[L, opt.Option[R]] into an opt.Option[Either[L, R]]. A right none maps to none. A right some maps to some wrapping right, and a left maps to some wrapping left.

Types

type Either

type Either[L, R any] struct {
	// contains filtered or unexported fields
}

func CloneCloner

func CloneCloner[L interface{ Clone() L }, R interface{ Clone() R }](e Either[L, R]) Either[L, R]

CloneCloner clones e by calling the Clone method on its held value.

For custom clone functions, use Either.CloneFunc. An Either[L, R] whose L and R only need a shallow copy can be copied by plain assignment.

func FlattenEither

func FlattenEither[L, R any](e Either[Either[L, R], Either[L, R]]) Either[L, R]

FlattenEither converts an Either[Either[L, R], Either[L, R]] into an Either[L, R], returning the inner either of whichever side e holds.

func FlattenLeft

func FlattenLeft[L, R any](e Either[Either[L, R], R]) Either[L, R]

FlattenLeft converts a nested Either[Either[L, R], R] into an Either[L, R]. The result is the inner either if e is left, Right[L] holding e's right value otherwise.

func FlattenRight

func FlattenRight[L, R any](e Either[L, Either[L, R]]) Either[L, R]

FlattenRight converts a nested Either[L, Either[L, R]] into an Either[L, R]. The result is the inner either if e is right, Left[L, R] holding e's left value otherwise.

func Left

func Left[L, R any](l L) Either[L, R]
func Right[L, R any](r R) Either[L, R]

func (Either[L, R]) CloneFunc

func (e Either[L, R]) CloneFunc(cloneL func(L) L, cloneR func(R) R) Either[L, R]

CloneFunc clones e using the cloneL or cloneR function for the held value.

func (Either[L, R]) EqualFunc

func (e Either[L, R]) EqualFunc(other Either[L, R], cmpL func(i, j L) bool, cmpR func(i, j R) bool) bool

EqualFunc tests e and other if both are left or right. If their state does not match, it returns false immediately. Otherwise it tests equality of the held values by cmpL or cmpR respectively.

If L and R are just comparable types, use Equal. If L and R are implementors of interface { Equal(t T) bool }, e.g time.Time, use EqualEqualer.

func (Either[L, R]) ExpectLeft

func (e Either[L, R]) ExpectLeft(msg string) L

ExpectLeft returns e's left value if e is left. Otherwise it panics with msg.

func (Either[L, R]) ExpectRight

func (e Either[L, R]) ExpectRight(msg string) R

ExpectRight returns e's right value if e is right. Otherwise it panics with msg.

func (Either[L, R]) Flip

func (e Either[L, R]) Flip() Either[R, L]

Flip converts Either[L, R] into Either[R, L], a left into a right and vice versa.

func (Either[L, R]) Fold

func (e Either[L, R]) Fold[U any](onLeft func(l L) U, onRight func(r R) U) U

Fold applies onLeft to a left value or onRight to a right value, squashing both cases into a single U.

func (Either[L, R]) InspectLeft

func (e Either[L, R]) InspectLeft(fn func(l L)) Either[L, R]

InspectLeft calls fn with e's left value if e is left, then returns e unchanged.

func (Either[L, R]) InspectRight

func (e Either[L, R]) InspectRight(fn func(r R)) Either[L, R]

InspectRight calls fn with e's right value if e is right, then returns e unchanged.

func (Either[L, R]) IsLeft

func (e Either[L, R]) IsLeft() bool

IsLeft returns true if e holds an L value. Note that the zero value of Either[L, R] is left holding the zero value of L.

func (Either[L, R]) IsLeftAnd

func (e Either[L, R]) IsLeftAnd(fn func(l L) bool) bool

IsLeftAnd returns true if e is left and calling fn with e's left value returns true. Otherwise it returns false.

func (Either[L, R]) IsRight

func (e Either[L, R]) IsRight() bool

IsRight returns true if e holds an R value.

func (Either[L, R]) IsRightAnd

func (e Either[L, R]) IsRightAnd(fn func(r R) bool) bool

IsRightAnd returns true if e is right and calling fn with e's right value returns true. Otherwise it returns false.

func (Either[L, R]) IterLeft

func (e Either[L, R]) IterLeft() iter.Seq[L]

IterLeft returns an iterator over the left value. If e is left, the iterator yields the left value, otherwise nothing.

func (Either[L, R]) IterRight

func (e Either[L, R]) IterRight() iter.Seq[R]

IterRight returns an iterator over the right value. If e is right, the iterator yields the right value, otherwise nothing.

func (Either[L, R]) Left

func (e Either[L, R]) Left() opt.Option[L]

Left converts e into opt.Option[L]. The option is some wrapping the left value if e is left, none otherwise.

func (Either[L, R]) LeftAnd

func (e Either[L, R]) LeftAnd[U any](u Either[U, R]) Either[U, R]

LeftAnd returns u if e is left, otherwise Right[U] holding e's right value.

func (Either[L, R]) LeftAndThen

func (e Either[L, R]) LeftAndThen[U any](fn func(l L) Either[U, R]) Either[U, R]

LeftAndThen calls fn with e's left value if e is left, otherwise returns Right[U] holding e's right value.

func (Either[L, R]) LeftOr

func (e Either[L, R]) LeftOr(l L) L

LeftOr returns e's left value if e is left, otherwise l.

func (Either[L, R]) LeftOrElse

func (e Either[L, R]) LeftOrElse(fn func(r R) L) L

LeftOrElse returns e's left value if e is left, otherwise the result of calling fn with e's right value.

func (Either[L, R]) LogValue

func (e Either[L, R]) LogValue() slog.Value

LogValue implements slog.LogValuer.

func (Either[L, R]) Map

func (e Either[L, R]) Map[L2, R2 any](onLeft func(l L) L2, onRight func(r R) R2) Either[L2, R2]

Map maps a left value by onLeft or a right value by onRight.

func (Either[L, R]) MapLeft

func (e Either[L, R]) MapLeft[U any](fn func(l L) U) Either[U, R]

MapLeft maps a left value by fn, leaving a right value untouched.

func (Either[L, R]) MapLeftOr

func (e Either[L, R]) MapLeftOr[U any](defaultValue U, fn func(l L) U) U

MapLeftOr returns e's left value applied by fn if e is left. Otherwise it returns defaultValue.

func (Either[L, R]) MapRight

func (e Either[L, R]) MapRight[U any](fn func(r R) U) Either[L, U]

MapRight maps a right value by fn, leaving a left value untouched.

func (Either[L, R]) MapRightOr

func (e Either[L, R]) MapRightOr[U any](defaultValue U, fn func(r R) U) U

MapRightOr returns e's right value applied by fn if e is right. Otherwise it returns defaultValue.

func (Either[L, R]) MarshalJSON

func (e Either[L, R]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

It encodes e as a JSON object with a single "left" or "right" key tagging the held value. For the untagged representation, use UntaggedEither.

func (Either[L, R]) MarshalJSONTo

func (e Either[L, R]) MarshalJSONTo(enc *jsontext.Encoder) error

MarshalJSONTo implements encoding/json/v2.MarshalerTo.

It encodes e as a JSON object with a single "left" or "right" key tagging the held value. For the untagged representation, use UntaggedEither.

func (Either[L, R]) MarshalXML

func (e Either[L, R]) MarshalXML(enc *xml.Encoder, start xml.StartElement) error

MarshalXML implements xml.Marshaler.

It encodes the held value wrapped in a <left> or <right> element tagging the side, e.g. <v><left>5</left></v>.

func (Either[L, R]) Right

func (e Either[L, R]) Right() opt.Option[R]

Right converts e into opt.Option[R]. The option is some wrapping the right value if e is right, none otherwise.

func (Either[L, R]) RightAnd

func (e Either[L, R]) RightAnd[U any](u Either[L, U]) Either[L, U]

RightAnd returns u if e is right, otherwise Left[L] holding e's left value.

func (Either[L, R]) RightAndThen

func (e Either[L, R]) RightAndThen[U any](fn func(r R) Either[L, U]) Either[L, U]

RightAndThen calls fn with e's right value if e is right, otherwise returns Left[L] holding e's left value.

func (Either[L, R]) RightOr

func (e Either[L, R]) RightOr(r R) R

RightOr returns e's right value if e is right, otherwise r.

func (Either[L, R]) RightOrElse

func (e Either[L, R]) RightOrElse(fn func(l L) R) R

RightOrElse returns e's right value if e is right, otherwise the result of calling fn with e's left value.

func (*Either[L, R]) UnmarshalJSON

func (e *Either[L, R]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

It decodes a JSON object with a single "left" or "right" key, storing the tagged value on the corresponding side.

func (*Either[L, R]) UnmarshalJSONFrom

func (e *Either[L, R]) UnmarshalJSONFrom(dec *jsontext.Decoder) error

UnmarshalJSONFrom implements encoding/json/v2.UnmarshalerFrom.

It decodes a JSON object with a single "left" or "right" key, storing the tagged value on the corresponding side.

func (*Either[L, R]) UnmarshalXML

func (e *Either[L, R]) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements xml.Unmarshaler.

It decodes an element containing a single <left> or <right> child element, storing the tagged value on the corresponding side.

func (Either[L, R]) Unpack

func (e Either[L, R]) Unpack() (l L, r R)

Unpack returns both internal values of e. The value for the side e does not hold is the zero value of its type.

func (Either[L, R]) UnwrapLeft

func (e Either[L, R]) UnwrapLeft() L

UnwrapLeft returns e's left value if e is left. Otherwise it panics.

func (Either[L, R]) UnwrapRight

func (e Either[L, R]) UnwrapRight() R

UnwrapRight returns e's right value if e is right. Otherwise it panics.

type Result

type Result[T any] struct {
	// contains filtered or unexported fields
}

func Err

func Err[T any](err error) Result[T]

Err returns a Result[T] holding err.

func Flatten

func Flatten[T any](r Result[Result[T]]) Result[T]

Flatten converts a nested Result[Result[T]] into a Result[T]. The result is the inner result if r is ok, Err[T] holding r's error otherwise.

func FromResult

func FromResult[T any](t T, err error) Result[T]

FromResult converts the conventional (t T, err error) pair into a Result[T]. The result is err if err is non nil, ok wrapping t otherwise.

func Ok

func Ok[T any](t T) Result[T]

Ok returns a Result[T] holding t.

func (Result[T]) And

func (r Result[T]) And[U any](u Result[U]) Result[U]

And returns u if r is ok, otherwise Err[U] holding r's error.

func (Result[T]) AndThen

func (r Result[T]) AndThen[U any](fn func(t T) Result[U]) Result[U]

AndThen calls fn with r's value if r is ok, otherwise returns Err[U] holding r's error.

func (Result[T]) Either

func (r Result[T]) Either() Either[T, error]

Either returns the internal either value.

func (Result[T]) Err

func (r Result[T]) Err() error

Err returns r's error if r is err, nil otherwise.

func (Result[T]) Expect

func (r Result[T]) Expect(msg string) T

Expect returns r's value if r is ok. Otherwise it panics with msg.

func (Result[T]) ExpectErr

func (r Result[T]) ExpectErr(msg string) error

ExpectErr returns r's error if r is err. Otherwise it panics with msg.

func (Result[T]) Inspect

func (r Result[T]) Inspect(fn func(t T)) Result[T]

Inspect calls fn with r's value if r is ok, then returns r unchanged.

func (Result[T]) InspectErr

func (r Result[T]) InspectErr(fn func(err error)) Result[T]

InspectErr calls fn with r's error if r is err, then returns r unchanged.

func (Result[T]) IsErr

func (r Result[T]) IsErr() bool

IsErr returns true if r holds an error.

func (Result[T]) IsErrAnd

func (r Result[T]) IsErrAnd(fn func(err error) bool) bool

IsErrAnd returns true if r is err and calling fn with r's error returns true. Otherwise it returns false.

func (Result[T]) IsOk

func (r Result[T]) IsOk() bool

IsOk returns true if r holds a T value.

func (Result[T]) IsOkAnd

func (r Result[T]) IsOkAnd(fn func(t T) bool) bool

IsOkAnd returns true if r is ok and calling fn with r's value returns true. Otherwise it returns false.

func (Result[T]) Iter

func (r Result[T]) Iter() iter.Seq[T]

Iter returns an iterator over the internal value. If r is ok, the iterator yields the value, otherwise nothing.

func (Result[T]) LogValue

func (r Result[T]) LogValue() slog.Value

LogValue implements slog.LogValuer, delegating to the internal either value.

func (Result[T]) Map

func (r Result[T]) Map[U any](fn func(t T) U) Result[U]

Map returns Ok[U] whose inner value is r's value mapped by fn if r is ok. Otherwise it returns Err[U] holding r's error.

func (Result[T]) MapErr

func (r Result[T]) MapErr(fn func(err error) error) Result[T]

MapErr returns Err[T] whose error is r's error mapped by fn if r is err. Otherwise it returns r unchanged.

func (Result[T]) MapOr

func (r Result[T]) MapOr[U any](defaultValue U, fn func(t T) U) U

MapOr returns r's value applied by fn if r is ok. Otherwise it returns defaultValue.

func (Result[T]) MapOrElse

func (r Result[T]) MapOrElse[U any](defaultFn func(err error) U, fn func(t T) U) U

MapOrElse returns r's value applied by fn if r is ok. Otherwise it returns the result of calling defaultFn with r's error.

func (Result[T]) MarshalJSON

func (r Result[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

It encodes r as a JSON object with a single "ok" or "err" key tagging the held value. The error is encoded as its message string, or the JSON null if it is nil. For the untagged representation, use UntaggedResult.

func (Result[T]) MarshalJSONTo

func (r Result[T]) MarshalJSONTo(enc *jsontext.Encoder) error

MarshalJSONTo implements encoding/json/v2.MarshalerTo.

It encodes r as a JSON object with a single "ok" or "err" key tagging the held value. The error is encoded as its message string, or the JSON null if it is nil. For the untagged representation, use UntaggedResult.

func (Result[T]) MarshalXML

func (r Result[T]) MarshalXML(enc *xml.Encoder, start xml.StartElement) error

MarshalXML implements xml.Marshaler.

It encodes the held value wrapped in an <ok> or <err> element tagging the side. The error is encoded as its message string, an empty one if it is nil.

func (Result[T]) Ok

func (r Result[T]) Ok() opt.Option[T]

Ok converts r into opt.Option[T]. The option is some wrapping the value if r is ok, none otherwise.

func (Result[T]) Or

func (r Result[T]) Or(u Result[T]) Result[T]

Or returns r if r is ok, otherwise u.

func (Result[T]) OrElse

func (r Result[T]) OrElse(fn func(err error) Result[T]) Result[T]

OrElse returns r if r is ok, otherwise calls fn with r's error and returns the result.

func (*Result[T]) UnmarshalJSON

func (r *Result[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

It decodes a JSON object with a single "ok" or "err" key. The "err" value must be a string or null; since the concrete error type is not recoverable, the error is reconstructed from the message with errors.New.

func (*Result[T]) UnmarshalJSONFrom

func (r *Result[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error

UnmarshalJSONFrom implements encoding/json/v2.UnmarshalerFrom.

It decodes a JSON object with a single "ok" or "err" key. The "err" value must be a string or null; since the concrete error type is not recoverable, the error is reconstructed from the message with errors.New.

func (*Result[T]) UnmarshalXML

func (r *Result[T]) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements xml.Unmarshaler.

It decodes an element containing a single <ok> or <err> child element. Since the concrete error type is not recoverable, the error is reconstructed from the message with errors.New.

func (Result[T]) Unwrap

func (r Result[T]) Unwrap() T

Unwrap returns r's value if r is ok. Otherwise it panics with the held error.

func (Result[T]) UnwrapErr

func (r Result[T]) UnwrapErr() error

UnwrapErr returns r's error if r is err. Otherwise it panics.

func (Result[T]) UnwrapOr

func (r Result[T]) UnwrapOr(t T) T

UnwrapOr returns r's value if r is ok, otherwise t.

func (Result[T]) UnwrapOrDefault

func (r Result[T]) UnwrapOrDefault() T

UnwrapOrDefault returns r's value if r is ok, otherwise the zero value of T.

func (Result[T]) UnwrapOrElse

func (r Result[T]) UnwrapOrElse(fn func(err error) T) T

UnwrapOrElse returns r's value if r is ok, otherwise the result of calling fn with r's error.

func (Result[T]) Value

func (r Result[T]) Value() T

Value returns r's value as T. T would be zero value if r is err.

type UntaggedEither

type UntaggedEither[L, R any] struct {
	Either[L, R]
}

UntaggedEither[L, R] adapts Either[L, R] to the untagged JSON representation: the held value is encoded directly, without the "left" or "right" tag object.

Since the encoding is untagged, unmarshaling first attempts to decode the value into L, then falls back to R; the first success wins. If L and R overlap (e.g. both decode from a JSON number), the value always lands on the left.

func (UntaggedEither[L, R]) MarshalJSON

func (u UntaggedEither[L, R]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (UntaggedEither[L, R]) MarshalJSONTo

func (u UntaggedEither[L, R]) MarshalJSONTo(enc *jsontext.Encoder) error

MarshalJSONTo implements encoding/json/v2.MarshalerTo.

func (UntaggedEither[L, R]) MarshalXML

func (u UntaggedEither[L, R]) MarshalXML(enc *xml.Encoder, start xml.StartElement) error

MarshalXML implements xml.Marshaler.

It encodes the held value directly into the start element, without the tagging child element.

func (*UntaggedEither[L, R]) UnmarshalJSON

func (u *UntaggedEither[L, R]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*UntaggedEither[L, R]) UnmarshalJSONFrom

func (u *UntaggedEither[L, R]) UnmarshalJSONFrom(dec *jsontext.Decoder) error

UnmarshalJSONFrom implements encoding/json/v2.UnmarshalerFrom.

func (*UntaggedEither[L, R]) UnmarshalXML

func (u *UntaggedEither[L, R]) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements xml.Unmarshaler.

It records the element's tokens and replays them, first attempting to decode the element into L, then falling back to R; the first success wins.

Mind that XML decoding is lenient and the sides overlap more often than in JSON: decoding into a struct virtually never fails, and empty content decodes into primitives as their zero value. In such cases the value lands on the left; use a strict xml.Unmarshaler implementor as L to make the fallback reachable.

type UntaggedResult

type UntaggedResult[T any] struct {
	Result[T]
}

UntaggedResult[T] adapts Result[T] to the untagged JSON representation: the held value is encoded directly, without the "ok" or "err" tag object. The error is encoded as its message string, or the JSON null if it is nil.

Since the encoding is untagged, unmarshaling first attempts to decode the value into T, then falls back to an error message string reconstructed with errors.New; the first success wins. If T also decodes from a JSON string, the value always lands on ok.

func (UntaggedResult[T]) MarshalJSON

func (u UntaggedResult[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (UntaggedResult[T]) MarshalJSONTo

func (u UntaggedResult[T]) MarshalJSONTo(enc *jsontext.Encoder) error

MarshalJSONTo implements encoding/json/v2.MarshalerTo.

func (UntaggedResult[T]) MarshalXML

func (u UntaggedResult[T]) MarshalXML(enc *xml.Encoder, start xml.StartElement) error

MarshalXML implements xml.Marshaler.

It encodes the held value directly into the start element, without the tagging child element. The error is encoded as its message string, an empty one if it is nil.

func (*UntaggedResult[T]) UnmarshalJSON

func (u *UntaggedResult[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*UntaggedResult[T]) UnmarshalJSONFrom

func (u *UntaggedResult[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error

UnmarshalJSONFrom implements encoding/json/v2.UnmarshalerFrom.

func (*UntaggedResult[T]) UnmarshalXML

func (u *UntaggedResult[T]) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements xml.Unmarshaler.

It records the element's tokens and replays them, first attempting to decode the element into T, then falling back to an error message string reconstructed with errors.New; the first success wins.

Mind that XML decoding is lenient and the sides overlap more often than in JSON: decoding into a struct virtually never fails, and empty content decodes into primitives as their zero value. In such cases the value lands on ok; use a strict xml.Unmarshaler implementor as T to make the fallback reachable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL