goresult

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2023 License: MPL-2.0 Imports: 2 Imported by: 0

README

goresult

Go reference documentation

Error handling with a generic Result[T] type, directly inspired from Rust's Result<T, E> type.

Example

package main

import (
    "errors"
    "fmt"

    rst "codeberg.org/whou/goresult"
)

func IntDiv(a, b int) rst.Result[int] {
    if b == 0 {
        return rst.Err[int](errors.New("oops! illegal division"))
    }

    return rst.Ok(a / b)
}

func main() {
    num := IntDiv(-4, 2).Unwrap()
    fmt.Println(num)

    // you may also use rst.Match(func, ok, err)
    num2 := IntDiv(2, 0).Match(
        func(n int) int {
            return n
        },
        func(err error) int {
            fmt.Println(err)
            return 0
        },
    )

    fmt.Println(num2)

    // Output:
    // -2
    // oops! illegal division
    // 0
}

License

goresult is licensed under MPL 2.0. You may freely copy, distribute and modify it. Modified files must also be released under MPL 2.0 or a GPL license. You can read the LICENSE file for more information.

Documentation

Overview

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func IntDiv(a, b int) rst.Result[int] {
	if b == 0 {
		return rst.Err[int](errors.New("oops! illegal division"))
	}

	return rst.Ok(a / b)
}

func main() {
	num := IntDiv(-4, 2).Unwrap()
	fmt.Println(num)

	// you may also use rst.Match(func, ok, err)
	num2 := IntDiv(2, 0).Match(
		func(n int) int {
			return n
		},
		func(err error) int {
			fmt.Println(err)
			return 0
		},
	)

	fmt.Println(num2)

}
Output:

-2
oops! illegal division
0

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Match

func Match[T any](r Result[T], ok func(T) T, err func(error) T) T

Match cases between an Ok value and an Err value and consume value from cases

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func IntDiv(a, b int) rst.Result[int] {
	if b == 0 {
		return rst.Err[int](errors.New("oops! illegal division"))
	}

	return rst.Ok(a / b)
}

func main() {
	num := rst.Match(IntDiv(-4, 2),
		func(n int) int {
			return n * -1
		},
		func(err error) int {
			return 0
		},
	)

	fmt.Println(num)

}
Output:

2

Types

type Result

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

func Err

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

Return a Result with an error

func Ok

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

Return a Result with a successful value

func (Result[T]) Expect

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

Return the contained Ok value or panic with a custom message

Example
package main

import (
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	num1 := rst.Ok(2).Expect("custom message")
	fmt.Println(num1)

	// panics with "custom message"
	// num2 := rst.Err[int]("error")).Expect("custom message")

}
Output:

2

func (Result[T]) ExpectErr

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

Return the contained Err value or panic if result is Ok with a custom error message and its value

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	someErrorType := errors.New("some error message")
	err := rst.Err[int](someErrorType).ExpectErr("Ok value panic")
	if errors.Is(err, someErrorType) {
		fmt.Println(err)
	}

	// panics with "Ok value panic"
	// err := rst.Ok(10).ExpectErr("Ok value panic")

}
Output:

some error message

func (Result[T]) IsErr

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

Returns true if the result is Err

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	rstOk := rst.Ok(5)
	fmt.Println(rstOk.IsErr())

	rstErr := rst.Err[int](errors.New("some error message"))
	fmt.Println(rstErr.IsErr())

}
Output:

false
true

func (Result[T]) IsErrAnd

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

Returns true if the result is Err and its value matches an evaluated function

Example
package main

import (
	"errors"
	"fmt"
	"os"

	rst "codeberg.org/whou/goresult"
)

func FileInfo(name string) rst.Result[os.FileInfo] {
	file, err := os.Stat(name)
	if err != nil {
		return rst.Err[os.FileInfo](err)
	}

	return rst.Ok(file)
}

func main() {
	// result is Err and the function returns true
	file1 := FileInfo("non-existent").IsErrAnd(func(err error) bool {
		return errors.Is(err, os.ErrNotExist)
	})
	fmt.Println(file1)

	// result is Err but the function returns false
	file2 := FileInfo("non-existent").IsErrAnd(func(err error) bool {
		return errors.Is(err, os.ErrPermission)
	})
	fmt.Println(file2)

	// result is Ok
	file3 := rst.Ok(123).IsErrAnd(func(err error) bool {
		return errors.Is(err, os.ErrNotExist)
	})
	fmt.Println(file3)

}
Output:

true
false
false

func (Result[T]) IsOk

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

Returs true if the result is Ok

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	rstOk := rst.Ok(5)
	fmt.Println(rstOk.IsOk())

	rstErr := rst.Err[int](errors.New("some error message"))
	fmt.Println(rstErr.IsOk())

}
Output:

true
false

func (Result[T]) IsOkAnd

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

Returns true if the result is Ok and its value matches an evaluated function

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	ten := rst.Ok(10).IsOkAnd(func(i int) bool {
		return i > 5
	})
	fmt.Println(ten)

	four := rst.Ok(4).IsOkAnd(func(i int) bool {
		return i > 5
	})
	fmt.Println(four)

	numErr := rst.Err[int](errors.New("error")).IsOkAnd(func(i int) bool {
		return i > 5
	})
	fmt.Println(numErr)

}
Output:

true
false
false

func (Result[T]) Map

func (r Result[T]) Map(fn func(T) T) Result[T]

Maps the result by applying a function to the Ok value

Example
package main

import (
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	phrase := "Result[T] is awesome!"

	count := rst.Ok(phrase).Map(func(s string) string {
		return fmt.Sprint(len(phrase))
	})

	fmt.Println(count.Unwrap())

}
Output:

21

func (Result[T]) MapOr

func (r Result[T]) MapOr(value T, fn func(T) T) T

Return the provided default if Err or apply a function to the contained Ok value

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	phrase := "Result[T] is awesome!"

	count := rst.Ok(phrase).MapOr("unable to map", func(s string) string {
		return fmt.Sprint(len(phrase))
	})
	fmt.Println(count)

	count2 := rst.Err[string](errors.New("error")).MapOr("unable to map", func(s string) string {
		return fmt.Sprint(len(phrase))
	})
	fmt.Println(count2)

}
Output:

21
unable to map

func (Result[T]) Match

func (r Result[T]) Match(ok func(T) T, err func(error) T) T

Match cases between an Ok value and an Err value and consume value from cases

func (Result[T]) Unwrap

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

Return the contained Ok value or panic with a generic error

Example
package main

import (
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	num1 := rst.Ok(2).Unwrap()
	fmt.Println(num1)

	// panics with "error"
	// num2 := rst.Err[int]("error").Unwrap()

}
Output:

2

func (Result[T]) UnwrapErr

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

Return the contained Err value or panic if result is Ok with its value

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	someErrorType := errors.New("some error message")
	err := rst.Err[int](someErrorType).UnwrapErr()
	if errors.Is(err, someErrorType) {
		fmt.Println(err)
	}

	// panics
	// err := rst.Ok(10).UnwrapErr()

}
Output:

some error message

func (Result[T]) UnwrapOr

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

Return the contained Ok value or a provided default value

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func main() {
	num := rst.Err[int](errors.New("some error message")).UnwrapOr(1)
	fmt.Println(num)

}
Output:

1

func (Result[T]) UnwrapOrDefault

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

Return the contained Ok value or return the default value from T

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func IntDiv(a, b int) rst.Result[int] {
	if b == 0 {
		return rst.Err[int](errors.New("oops! illegal division"))
	}

	return rst.Ok(a / b)
}

func main() {
	num1 := IntDiv(20, 5).UnwrapOrDefault()
	fmt.Println(num1)

	// int type default value is 0
	num2 := IntDiv(20, 0).UnwrapOrDefault()
	fmt.Println(num2)

}
Output:

4
0

func (Result[T]) UnwrapOrElse

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

Return the contained Ok value or return the evaluated function

Example
package main

import (
	"errors"
	"fmt"

	rst "codeberg.org/whou/goresult"
)

func IntDiv(a, b int) rst.Result[int] {
	if b == 0 {
		return rst.Err[int](errors.New("oops! illegal division"))
	}

	return rst.Ok(a / b)
}

func main() {
	num1 := IntDiv(20, 5).UnwrapOrElse(func() int {
		return -1
	})
	fmt.Println(num1)

	num2 := IntDiv(20, 0).UnwrapOrElse(func() int {
		return -1
	})
	fmt.Println(num2)

}
Output:

4
-1

Jump to

Keyboard shortcuts

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