ba0918/result

Rust-inspired Result and Option types for PHP, with immutable design and full type safety

Maintainers

Package info

github.com/ba0918/result

pkg:composer/ba0918/result

Transparency log

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-08-15 03:30 UTC

This package is auto-updated.

Last update: 2026-08-15 03:32:43 UTC


README

PHP Version PHPStan Tests Coverage

日本語

A PHP implementation of Rust's Result and Option types for robust error handling and null safety.

Features

  • Type-safe error handling - express success/failure explicitly instead of using exceptions or null
  • Functional programming - declarative code through method chaining
  • Rust compatible - 97% specification compliance with the Rust standard library
  • High quality - PHPStan Level MAX, 100% test coverage

Table of Contents

  1. Installation
  2. Quick Start
  3. Documentation
  4. Key Features
  5. Requirements
  6. Development
  7. License

Installation

composer require ba0918/result

Quick Start

Result Type - Error Handling

<?php
use ba0918\Result\{Ok, Err, Result};

// Division function (handles division by zero as error)
function safeDivide(float $a, float $b): Result
{
    if ($b === 0.0) {
        return Err::of("Cannot divide by zero");
    }
    return Ok::of($a / $b);
}

// Error handling
$result = safeDivide(10, 2);

if ($result->isOk()) {
    echo "Result: " . $result->unwrap(); // Result: 5
} else {
    echo "Error: " . $result->unwrapErr();
}

// More concise with method chaining
$output = safeDivide(10, 2)
    ->map(fn($value) => $value * 2)        // Double on success
    ->unwrapOr(0);                         // Default to 0 on failure

echo $output; // 10

Option Type - Null Safety

<?php
use ba0918\Result\{Some, None, Option};

// Safely retrieve value from array
function findUser(int $id): Option
{
    $users = [1 => 'Alice', 2 => 'Bob'];
    
    if (isset($users[$id])) {
        return Some::of($users[$id]);
    }
    return None::instance();
}

// Null-safe processing
$user = findUser(1)
    ->map(fn($name) => strtoupper($name))  // Uppercase if found
    ->unwrapOr('Unknown');                 // Default value if not found

echo $user; // ALICE

Documentation

Tutorials

Guides

References

Comparisons

Examples

Key Features

Result Type Methods

// Core methods
$result->isOk() / $result->isErr()           // Success/failure checks
$result->map($fn) / $result->mapErr($fn)     // Value/error transformation
$result->andThen($fn)                        // Monadic chaining
$result->unwrap() / $result->unwrapOr($def)  // Value extraction

// Shorthand methods
$result->isOkAnd($predicate)                 // Conditional success check
$result->mapOr($fn, $default)                // Transformation with default

Option Type Methods

// Core methods
$option->isSome() / $option->isNone()        // Value presence checks
$option->map($fn)                            // Value transformation
$option->andThen($fn)                        // Monadic chaining
$option->filter($predicate)                  // Conditional filtering

// Combining operations
$option->zip($other)                         // Combine two Options
$option->xor($other)                         // Exclusive OR

Pipe Operator API (PHP 8.5+)

use function ba0918\Result\Pipe\{andThen, map, mapErr, orElse};

$response = $this->doSomething()
    |> andThen(fn ($value) => $this->transform($value))
    |> orElse(fn ($error) => $this->recover($error))
    |> andThen(fn ($value) => $this->respond($value));

The ba0918\Result\Pipe functions are thin adapters over the same-named Result methods. Each returned closure's input type is bound to the callable's parameter type (map(fn (int $v) ...) accepts Result<int, E>), so piping a mismatched Result into a stage is a static error under PHPStan. The pipe operator itself does not short-circuit — only the business callable passed to each operator is skipped on Ok/Err. The adapters also work without |> (andThen($op)($result)) on PHP 8.3/8.4.

Requirements

  • PHP 8.3+ (the |> syntax at call sites requires PHP 8.5 or later)
  • Composer

Development

# Install dependencies
composer install

# Run tests
composer test

# Static analysis
composer phpstan

# Code style check
composer cs-check

# All quality checks
composer check

License

MIT