bosunski/results

Rust-like Result/Option PHP 工具库

v0.0.1 2024-01-14 17:06 UTC

This package is auto-updated.

Last update: 2024-09-19 21:34:23 UTC


README

Results 是一个简单的 (无依赖) PHP 库,它提供了一组辅助函数和类,用于处理可选值和操作的结果。它受到了 Rust 中的 OptionResult 类型的影响。实现本身基于名为 ts-results 的 TypeScript 实现。

安装

您可以通过 Composer 安装此库

composer require bosunski/results

使用

演示

您可以在这个 沙盒 中尝试此包

Option

Option 类型表示一个可选值:每个 Option 要么是包含值的 Some,要么是不包含值的 None

<?php

use function Bosunski\Results\Option;

$some = Option('value'); // Some
$none = Option(null); // None

Result

Result 类型是一个表示成功(Ok)或失败(Err)的类型。

<?php

use function Bosunski\Results\Result;

$ok = Result('value'); // Ok
$err = Result(new Exception('error')); // Err

辅助函数

该库提供了一组用于创建 OptionResult 实例的辅助函数

  • Some(mixed $value): Some
  • None(): None
  • Option(mixed $value): Option
  • Ok(mixed $value): Ok
  • Err(Throwable $e): Err
  • Result(mixed $value): Ok|Err
  • wrap(callable $fn): Result

示例

PHP 中可以使用 Results 库提供的 OptionResult 类型来表示可选值和结果。以下是一些示例

<?php

use function Bosunski\Results\Option;
use function Bosunski\Results\Result;

// Options
$some = Option('value'); // Some
$none = Option(null); // None

// Results
$ok = Result('value'); // Ok
$err = Result(new Exception('error')); // Err

在上面的示例中

  • Option('value') 创建了一个包含值的 Option(称为 Some)。
  • Option(null) 创建了一个不包含值的 Option(称为 None)。
  • Result('value') 创建了一个表示成功操作的 ResultOk)。
  • Result(new Exception('error')) 创建了一个表示失败操作的 ResultErr)。

让我们深入了解在 PHP 中使用 OptionResult 类型的一些更复杂的示例。

考虑一个可能返回或不返回值的函数。我们可以使用 Option 类型来处理这种不确定性。

<?php

use Bosunski\Results\Option as OptionInterface;
use function Bosunski\Results\Option;

function findUserById($id): OptionInterface {
    // Assume getUserFromDatabase is a function that returns a User object if found, null otherwise
    $user = getUserFromDatabase($id);
    
    return Option($user);
}

$userOption = findUserById(123);

// We can then handle the optional value using the methods provided by the Option type
if ($userOption->isSome()) {
    $user = $userOption->unwrap();
    // Do something with the user
} else {
    // Handle the case where no user was found
}

// You can also do this
$user = $userOption->unwrap() // Throws error if null

现在,让我们考虑一个可能成功或失败的函数。我们可以使用 Result 类型来处理这种情况。

<?php

use Bosunski\Results\Result\Result as ResultInterface;
use function Bosunski\Results\Result;

function divide(int $numerator, int $denominator): ResultInterface {
    if ($denominator == 0) {
        return Err(new Exception("Cannot divide by zero"));
    } else {
        return Ok($numerator / $denominator);
    }
}

$result = divide(10, 0);

// We can then handle the result using the methods provided by the Result type
if ($result->isOk()) {
    $value = $result->unwrap();
    // Do something with the value
} else {
    $error = $result->unwrapErr();
    // Handle the error
}

// You can also do this
$user = $result->unwrap() // Throws error if an error is present

在这些示例中,OptionResult 类型提供了一种安全且易于表达的方式来处理可选值和操作的结果。

wrap 函数

wrap 函数是库提供的一个实用函数。它设计用于处理可能抛出错误的操作。wrap 函数执行一个 callable 并返回其结果被包裹在一个 Result 对象中。如果可调用函数抛出异常,wrap 函数会捕获它并返回一个包含异常的 Err 对象。

重要

wrap 函数只会捕获 Throwable 实例。如果你的函数引发了一个致命错误,它将不会被 wrap 捕获。

以下是如何使用 wrap 函数的一个示例

<?php

use function Bosunski\Results\wrap;

function mightThrowException(): int {
    if (rand(0, 1) === 1) {
        throw new Exception('An error occurred');
    }

    return 42;
}

$result = wrap(mightThrowException(...));

if ($result->isOk()) {
    echo "Success: " . $result->unwrap();
} else {
    echo "Error: " . $result->unwrapErr()->getMessage();
}

在这个例子中,mightThrowException 是一个可能会抛出异常的函数。我们将这个函数传递给 wrap,它执行该函数,捕获 任何 错误并将结果封装在 Result 对象中。然后我们检查结果是否是 OkErr 的实例,并相应地处理。

wrap 函数提供了一种安全且易于表达的方式来处理可能会抛出错误的操作,让你在不需要处理错误时,能够专注于应用程序逻辑。

贡献

设置项目

你可以通过运行以下命令来安装开发依赖项:

composer install

运行测试

composer run test

许可证

本项目采用 MIT 许可证 许可。