{"id":36372352,"url":"https://github.com/brimmar/phpresult","last_synced_at":"2026-01-11T14:01:54.457Z","repository":{"id":251300935,"uuid":"835376959","full_name":"brimmar/phpresult","owner":"brimmar","description":"PHP implementation of a Rust-like Result Type","archived":false,"fork":false,"pushed_at":"2025-12-17T13:55:22.000Z","size":124,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-21T02:17:05.808Z","etag":null,"topics":["developer-tools","error-handling","library","packagist","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brimmar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2024-07-29T17:53:31.000Z","updated_at":"2025-12-17T13:55:25.000Z","dependencies_parsed_at":"2024-08-02T04:13:42.766Z","dependency_job_id":"78d99d49-c12b-4f3d-ae95-758c053f7990","html_url":"https://github.com/brimmar/phpresult","commit_stats":null,"previous_names":["brimmar/phpresult"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/brimmar/phpresult","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brimmar%2Fphpresult","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brimmar%2Fphpresult/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brimmar%2Fphpresult/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brimmar%2Fphpresult/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brimmar","download_url":"https://codeload.github.com/brimmar/phpresult/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brimmar%2Fphpresult/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28306985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T11:18:18.743Z","status":"ssl_error","status_checked_at":"2026-01-11T11:07:56.842Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","error-handling","library","packagist","php"],"created_at":"2026-01-11T14:01:54.395Z","updated_at":"2026-01-11T14:01:54.447Z","avatar_url":"https://github.com/brimmar.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP Result Type Documentation\n[![Tests](https://github.com/brimmar/phpresult/actions/workflows/tests.yml/badge.svg)](https://github.com/brimmar/phpresult/actions/workflows/tests.yml)\n[![Static Analysis](https://github.com/brimmar/phpresult/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/brimmar/phpresult/actions/workflows/static-analysis.yml)\n[![License](https://img.shields.io/packagist/l/brimmar/phpresult)](https://packagist.org/packages/brimmar/phpresult)\n[![Latest Stable Version](https://img.shields.io/packagist/v/brimmar/phpresult)](https://packagist.org/packages/brimmar/phpresult)\n[![Total Downloads](https://img.shields.io/packagist/dt/brimmar/phpresult)](https://packagist.org/packages/brimmar/phpresult)\n\nThis documentation covers the implementation of a Rust-like Result Type for PHP. The Result type is used for returning and propagating errors. It has two variants: `Ok`, representing success and containing a value, and `Err`, representing error and containing an error value.\n\n## Table of Contents\n\n1. [Result Interface](#result-interface)\n2. [Usage](#usage)\n3. [Methods](#methods)\n4. [Complementary Packages](#complementary-packages)\n5. [Static Analysis](#static-analysis)\n6. [Contributing](#contributing)\n7. [Security Vulnerabilities](#security-vulnerabilities)\n8. [License](#License)\n\n## Result Interface\n\nThe `Result` interface defines the contract for both `Ok` and `Err` classes.\n\n```php\n\u003c?php\n\nnamespace Brimmar\\PhpResult\\Interfaces;\n\n/**\n * @template T\n * @template E\n */\ninterface Result\n{\n    // ... (methods will be documented below)\n}\n```\n\n## Usage\n\n#### First Example\n\n```php\n\u003c?php\nuse Brimmar\\PhpResult\\Ok;\nuse Brimmar\\PhpResult\\Err;\nuse Brimmar\\PhpResult\\Interfaces\\Result;\n\nclass UserRegistration\n{\n    private $db;\n    private $emailService;\n\n    public function __construct(Database $db, EmailService $emailService)\n    {\n        $this-\u003edb = $db;\n        $this-\u003eemailService = $emailService;\n    }\n\n    public function registerUser(string $username, string $email, string $password): Result\n    {\n        return $this-\u003evalidateInput($username, $email, $password)\n            -\u003eandThen(fn() =\u003e $this-\u003echeckUserExists($username, $email))\n            -\u003eandThen(fn() =\u003e $this-\u003ehashPassword($password))\n            -\u003eandThen(fn($hashedPassword) =\u003e $this-\u003esaveUser($username, $email, $hashedPassword))\n            -\u003eandThen(fn($userId) =\u003e $this-\u003esendWelcomeEmail($userId, $email));\n    }\n\n    private function validateInput(string $username, string $email, string $password): Result\n    {\n        if (strlen($username) \u003c 3) {\n            return new Err(\"Username must be at least 3 characters long\");\n        }\n        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {\n            return new Err(\"Invalid email address\");\n        }\n        if (strlen($password) \u003c 8) {\n            return new Err(\"Password must be at least 8 characters long\");\n        }\n        return new Ok(null);\n    }\n\n    private function checkUserExists(string $username, string $email): Result\n    {\n        $exists = $this-\u003edb-\u003equery(\"SELECT id FROM users WHERE username = ? OR email = ?\", [$username, $email])-\u003efetchColumn();\n        return $exists ? new Err(\"Username or email already exists\") : new Ok(null);\n    }\n\n    private function hashPassword(string $password): Result\n    {\n        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);\n        return $hashedPassword ? new Ok($hashedPassword) : new Err(\"Failed to hash password\");\n    }\n\n    private function saveUser(string $username, string $email, string $hashedPassword): Result\n    {\n        $userId = $this-\u003edb-\u003einsert(\"INSERT INTO users (username, email, password) VALUES (?, ?, ?)\", [$username, $email, $hashedPassword]);\n        return $userId ? new Ok($userId) : new Err(\"Failed to save user to database\");\n    }\n\n    private function sendWelcomeEmail(int $userId, string $email): Result\n    {\n        $sent = $this-\u003eemailService-\u003esend($email, \"Welcome to our service!\", \"Thank you for registering...\");\n        return $sent ? new Ok($userId) : new Err(\"Failed to send welcome email\");\n    }\n}\n\n$registration = new UserRegistration($db, $emailService);\n$result = $registration-\u003eregisterUser(\"johndoe\", \"john@example.com\", \"password123\")-\u003ematch(\n    Ok: fn($value) =\u003e echo \"User registered successfully with ID: $value\",\n    Err: fn($error) =\u003e echo \"Registration failed: $error\",\n);\n```\n\n#### Second Example\n\n```php\n\u003c?php\nuse Brimmar\\PhpResult\\Ok;\nuse Brimmar\\PhpResult\\Err;\nuse Brimmar\\PhpResult\\Interfaces\\Result;\n\nclass WeatherApiClient\n{\n    private $httpClient;\n    private $cache;\n    private $rateLimiter;\n    private $apiKey;\n\n    public function __construct(HttpClient $httpClient, CacheInterface $cache, RateLimiter $rateLimiter, string $apiKey)\n    {\n        $this-\u003ehttpClient = $httpClient;\n        $this-\u003ecache = $cache;\n        $this-\u003erateLimiter = $rateLimiter;\n        $this-\u003eapiKey = $apiKey;\n    }\n\n    public function getWeatherForecast(string $city): Result\n    {\n        return $this-\u003echeckRateLimit()\n            -\u003eandThen(fn() =\u003e $this-\u003egetCachedForecast($city))\n            -\u003eorElse(fn() =\u003e $this-\u003efetchForecastFromApi($city))\n            -\u003eandThen(fn($forecast) =\u003e $this-\u003ecacheForecast($city, $forecast));\n    }\n\n    private function checkRateLimit(): Result\n    {\n        return $this-\u003erateLimiter-\u003eisAllowed('weather_api')\n            ? new Ok(null)\n            : new Err(\"Rate limit exceeded. Please try again later.\");\n    }\n\n    private function getCachedForecast(string $city): Result\n    {\n        $cachedForecast = $this-\u003ecache-\u003eget(\"weather_forecast:$city\");\n        return $cachedForecast ? new Ok($cachedForecast) : new Err(\"Cache miss\");\n    }\n\n    private function fetchForecastFromApi(string $city): Result\n    {\n        try {\n            $response = $this-\u003ehttpClient-\u003eget(\"https://api.weather.com/forecast\", [\n                'query' =\u003e ['city' =\u003e $city, 'apikey' =\u003e $this-\u003eapiKey]\n            ]);\n\n            if ($response-\u003egetStatusCode() !== 200) {\n                return new Err(\"API request failed with status code: \" . $response-\u003egetStatusCode());\n            }\n\n            $forecast = json_decode($response-\u003egetBody(), true);\n            return new Ok($forecast);\n        } catch (\\Exception $e) {\n            return new Err(\"Failed to fetch forecast: \" . $e-\u003egetMessage());\n        }\n    }\n\n    private function cacheForecast(string $city, array $forecast): Result\n    {\n        $cached = $this-\u003ecache-\u003eset(\"weather_forecast:$city\", $forecast, 3600); // Cache for 1 hour\n        return $cached ? new Ok($forecast) : new Err(\"Failed to cache forecast\");\n    }\n}\n\n$weatherClient = new WeatherApiClient($httpClient, $cache, $rateLimiter, 'your-api-key');\n$result = $weatherClient-\u003egetWeatherForecast(\"New York\")-\u003ematch(\n    Ok: fn($value) =\u003e echo \"Weather forecast for New York: $value['summary']\",\n    Err: fn($error) =\u003e echo \"Failed to get weather forecast: $error\",\n);;\n```\n\n#### Third Example\n\n```php\n\u003c?php\nuse Brimmar\\PhpResult\\Ok;\nuse Brimmar\\PhpResult\\Err;\nuse Brimmar\\PhpResult\\Interfaces\\Result;\n\nclass ConfigManager\n{\n    private $configs = [];\n\n    public function getConfig(string $key): Result\n    {\n        return $this-\u003egetFromEnvironment($key)\n            -\u003eor($this-\u003egetFromFile($key))\n            -\u003eorElse(fn() =\u003e $this-\u003egetDefaultConfig($key));\n    }\n\n    private function getFromEnvironment(string $key): Result\n    {\n        $value = getenv($key);\n        return $value !== false ? new Ok($value) : new Err(\"Not found in environment\");\n    }\n\n    private function getFromFile(string $key): Result\n    {\n        return isset($this-\u003econfigs[$key])\n            ? new Ok($this-\u003econfigs[$key])\n            : new Err(\"Not found in config file\");\n    }\n\n    private function getDefaultConfig(string $key): Result\n    {\n        $defaults = ['timeout' =\u003e 30, 'retries' =\u003e 3];\n        return isset($defaults[$key])\n            ? new Ok($defaults[$key])\n            : new Err(\"No default value for $key\");\n    }\n\n    public function setConfig(string $key, $value): void\n    {\n        $this-\u003econfigs[$key] = $value;\n    }\n}\n\n$manager = new ConfigManager();\n$manager-\u003esetConfig('database_url', 'mysql://localhost/mydb');\n\n$dbConfig = $manager-\u003egetConfig('database_url')\n    -\u003emap(fn($url) =\u003e parse_url($url))\n    -\u003eisOkAnd(fn($parsed) =\u003e isset($parsed['scheme'], $parsed['host'], $parsed['path']));\n\nif ($dbConfig) {\n    echo \"Valid database configuration found\";\n} else {\n    echo \"Invalid or missing database configuration\";\n}\n\n$timeout = $manager-\u003egetConfig('timeout')\n    -\u003eexpect(\"Timeout configuration is required\");\n\necho \"Timeout set to: $timeout\";\n```\n\n#### Fourth Example\n\n```php\n\u003c?php\nuse Brimmar\\PhpResult\\Ok;\nuse Brimmar\\PhpResult\\Err;\nuse Brimmar\\PhpResult\\Interfaces\\Result;\nuse Brimmar\\PhpOption\\Some;\nuse Brimmar\\PhpOption\\None;\nuse Brimmar\\PhpOption\\Interfaces\\Option;\n\nclass UserService\n{\n    private $users = [];\n\n    public function findUser(int $id): Option\n    {\n        return isset($this-\u003eusers[$id]) ? new Some($this-\u003eusers[$id]) : new None();\n    }\n\n    public function updateUser(int $id, array $data): Result\n    {\n        return $this-\u003efindUser($id)\n            -\u003eok()\n            -\u003emapErr(fn() =\u003e \"User not found\")\n            -\u003eandThen(fn($user) =\u003e $this-\u003evalidateUserData($data))\n            -\u003emap(fn($validData) =\u003e array_merge($this-\u003eusers[$id], $validData))\n            -\u003einspect(fn($updatedUser) =\u003e $this-\u003eusers[$id] = $updatedUser);\n    }\n\n    private function validateUserData(array $data): Result\n    {\n        $errors = array_filter([\n            'name' =\u003e strlen($data['name'] ?? '') \u003c 2 ? 'Name too short' : null,\n            'email' =\u003e filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL) ? null : 'Invalid email',\n        ]);\n\n        return empty($errors) ? new Ok($data) : new Err($errors);\n    }\n\n    public function getUserStats(): array\n    {\n        return array_map(\n            fn($user) =\u003e $this-\u003ecalculateUserScore($user)-\u003eunwrapOr(0),\n            $this-\u003eusers\n        );\n    }\n\n    private function calculateUserScore(array $user): Option\n    {\n        return isset($user['activities'])\n            ? new Some(array_sum($user['activities']))\n            : new None();\n    }\n}\n\n$service = new UserService();\n\n// Simulate adding a user\n$service-\u003eusers[1] = ['name' =\u003e 'Alice', 'email' =\u003e 'alice@example.com'];\n\n$updateResult = $service-\u003eupdateUser(1, ['name' =\u003e 'Alicia'])\n    -\u003etranspose();\n\n$name = $updateResult\n    -\u003eiter()\n    -\u003ecurrent()['name'] ?? 'Unknown';\n\necho \"Updated name: $name\";\n\n$stats = $service-\u003egetUserStats();\necho \"User stats: \" . implode(', ', $stats);\n```\n\n### Methods\n\n#### `isOk(): bool`\n\nReturns `true` if the result is `Ok`.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eisOk(); // Output: true\n\n$result = new Err(\"error\");\necho $result-\u003eisOk(); // Output: false\n```\n\n#### `isOkAnd(callable $fn): bool`\n\nReturns `true` if the result is `Ok` and the value inside of it matches a predicate.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eisOkAnd(fn($value) =\u003e $value \u003e 40); // Output: true\necho $result-\u003eisOkAnd(fn($value) =\u003e $value \u003c 40); // Output: false\n\n$result = new Err(\"error\");\necho $result-\u003eisOkAnd(fn($value) =\u003e true); // Output: false\n```\n\n#### `isErr(): bool`\n\nReturns `true` if the result is `Err`.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eisErr(); // Output: false\n\n$result = new Err(\"error\");\necho $result-\u003eisErr(); // Output: true\n```\n\n#### `isErrAnd(callable $fn): bool`\n\nReturns `true` if the result is `Err` and the value inside of it matches a predicate.\n\nExample:\n\n```php\n$result = new Err(\"error\");\necho $result-\u003eisErrAnd(fn($error) =\u003e $error === \"error\"); // Output: true\necho $result-\u003eisErrAnd(fn($error) =\u003e $error === \"other\"); // Output: false\n\n$result = new Ok(42);\necho $result-\u003eisErrAnd(fn($error) =\u003e true); // Output: false\n```\n\n#### `ok(?string $className): mixed`\n\nConverts from `Result\u003cT, E\u003e` to `Option\u003cT\u003e`.\n\nExample:\n\n```php\n$result = new Ok(42);\n$option = $result-\u003eok('\\Brimmar\\PhpOption\\Some');\necho $option-\u003eunwrap(); // Output: 42\n\n$result = new Err(\"error\");\n$option = $result-\u003eok('\\Brimmar\\PhpOption\\None');\necho $option-\u003eisNone(); // Output: true\n```\n\n#### `err(?string $className): mixed`\n\nConverts from `Result\u003cT, E\u003e` to `Option\u003cE\u003e`.\n\nExample:\n\n```php\n$result = new Ok(42);\n$option = $result-\u003eerr('\\Brimmar\\PhpOption\\None');\necho $option-\u003eisNone(); // Output: true\n\n$result = new Err(\"error\");\n$option = $result-\u003eerr('\\Brimmar\\PhpOption\\Some');\necho $option-\u003eunwrap(); // Output: \"error\"\n```\n\n#### `unwrap(): mixed`\n\nReturns the contained `Ok` value. Throws an exception if the value is an `Err`.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eunwrap(); // Output: 42\n\n$result = new Err(\"error\");\n$result-\u003eunwrap(); // Throws RuntimeException\n```\n\n#### `expect(string $msg): mixed`\n\nReturns the contained `Ok` value. Throws an exception with a provided message if the value is an `Err`.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eexpect(\"Failed to get value\"); // Output: 42\n\n$result = new Err(\"error\");\n$result-\u003eexpect(\"Failed to get value\"); // Throws RuntimeException with message \"Failed to get value: error\"\n```\n\n#### `expectErr(string $msg): mixed`\n\nReturns the contained `Err` value. Throws an exception with a provided message if the value is an `Ok`.\n\nExample:\n\n```php\n$result = new Err(\"error\");\necho $result-\u003eexpectErr(\"Failed to get error\"); // Output: \"error\"\n\n$result = new Ok(42);\n$result-\u003eexpectErr(\"Failed to get error\"); // Throws RuntimeException with message \"Failed to get error: 42\"\n```\n\n#### `flatten(): Result`\n\nConverts from `Result\u003cResult\u003cT, E\u003e, E\u003e` to `Result\u003cT, E\u003e`.\n\nExample:\n\n```php\n$result = new Ok(new Ok(42));\n$flattened = $result-\u003eflatten();\necho $flattened-\u003eunwrap(); // Output: 42\n\n$result = new Ok(new Err(\"inner error\"));\n$flattened = $result-\u003eflatten();\necho $flattened-\u003eunwrapErr(); // Output: \"inner error\"\n\n$result = new Err(\"outer error\");\n$flattened = $result-\u003eflatten();\necho $flattened-\u003eunwrapErr(); // Output: \"outer error\"\n```\n\n#### `intoErr(): mixed`\n\nReturns the contained `Err` value. Throws an exception if the value is an `Ok`.\n\nExample:\n\n```php\n$result = new Err(\"error\");\necho $result-\u003eintoErr(); // Output: \"error\"\n\n$result = new Ok(42);\n$result-\u003eintoErr(); // Throws RuntimeException\n```\n\n#### `intoOk(): mixed`\n\nReturns the contained `Ok` value. Throws an exception if the value is an `Err`.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eintoOk(); // Output: 42\n\n$result = new Err(\"error\");\n$result-\u003eintoOk(); // Throws RuntimeException\n```\n\n#### `iter(): Iterator`\n\nReturns an iterator over the possibly contained value.\n\nExample:\n\n```php\n$result = new Ok(42);\nforeach ($result-\u003eiter() as $value) {\n    echo $value; // Output: 42\n}\n\n$result = new Err(\"error\");\nforeach ($result-\u003eiter() as $value) {\n    echo \"This won't be executed\";\n}\n```\n\n#### `unwrapOr(mixed $default): mixed`\n\nReturns the contained `Ok` value or a provided default.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eunwrapOr(0); // Output: 42\n\n$result = new Err(\"error\");\necho $result-\u003eunwrapOr(0); // Output: 0\n```\n\n#### `unwrapOrElse(callable $fn): mixed`\n\nReturns the contained `Ok` value or computes it from a closure.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003eunwrapOrElse(fn() =\u003e 0); // Output: 42\n\n$result = new Err(\"error\");\necho $result-\u003eunwrapOrElse(fn($error) =\u003e strlen($error)); // Output: 5\n```\n\n#### `map(callable $fn): Result`\n\nMaps a `Result\u003cT, E\u003e` to `Result\u003cU, E\u003e` by applying a function to a contained `Ok` value, leaving an `Err` value untouched.\n\nExample:\n\n```php\n$result = new Ok(42);\n$mapped = $result-\u003emap(fn($value) =\u003e $value * 2);\necho $mapped-\u003eunwrap(); // Output: 84\n\n$result = new Err(\"error\");\n$mapped = $result-\u003emap(fn($value) =\u003e $value * 2);\necho $mapped-\u003eunwrapErr(); // Output: \"error\"\n```\n\n#### `mapErr(callable $fn): Result`\n\nMaps a `Result\u003cT, E\u003e` to `Result\u003cT, F\u003e` by applying a function to a contained `Err` value, leaving an `Ok` value untouched.\n\nExample:\n\n```php\n$result = new Err(\"error\");\n$mapped = $result-\u003emapErr(fn($error) =\u003e strtoupper($error));\necho $mapped-\u003eunwrapErr(); // Output: \"ERROR\"\n\n$result = new Ok(42);\n$mapped = $result-\u003emapErr(fn($error) =\u003e strtoupper($error));\necho $mapped-\u003eunwrap(); // Output: 42\n```\n\n#### `mapOr(mixed $default, callable $fn): mixed`\n\nReturns the provided default (if `Err`), or applies a function to the contained value (if `Ok`).\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003emapOr(0, fn($value) =\u003e $value * 2); // Output: 84\n\n$result = new Err(\"error\");\necho $result-\u003emapOr(0, fn($value) =\u003e $value * 2); // Output: 0\n```\n\n#### `mapOrElse(callable $default, callable $fn): mixed`\n\nMaps a `Result\u003cT, E\u003e` to `U` by applying fallback function `default` to a contained `Err` value, or function `fn` to a contained `Ok` value.\n\nExample:\n\n```php\n$result = new Ok(42);\necho $result-\u003emapOrElse(\n    fn($error) =\u003e strlen($error),\n    fn($value) =\u003e $value * 2\n); // Output: 84\n\n$result = new Err(\"error\");\necho $result-\u003emapOrElse(\n    fn($error) =\u003e strlen($error),\n    fn($value) =\u003e $value * 2\n); // Output: 5\n```\n\n#### `inspect(callable $fn): self`\n\nCalls the provided closure with a reference to the contained value (if `Ok`).\n\nExample:\n\n```php\n$result = new Ok(42);\n$result-\u003einspect(function($value) {\n    echo \"Got value: $value\";\n}); // Output: Got value: 42\n\n$result = new Err(\"error\");\n$result-\u003einspect(function($value) {\n    echo \"This won't be executed\";\n});\n```\n\n#### `inspectErr(callable $fn): self`\n\nCalls the provided closure with a reference to the contained error (if `Err`).\n\nExample:\n\n```php\n$result = new Err(\"error\");\n$result-\u003einspectErr(function($error) {\n    echo \"Got error: $error\";\n}); // Output: Got error: error\n\n$result = new Ok(42);\n$result-\u003einspectErr(function($error) {\n    echo \"This won't be executed\";\n});\n```\n\n#### `and(Result $res): Result`\n\nReturns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.\n\nExample:\n\n```php\n$result1 = new Ok(42);\n$result2 = new Ok(10);\n$combined = $result1-\u003eand($result2);\necho $combined-\u003eunwrap(); // Output: 10\n\n$result1 = new Err(\"error\");\n$result2 = new Ok(10);\n$combined = $result1-\u003eand($result2);\necho $combined-\u003eunwrapErr(); // Output: \"error\"\n```\n\n#### `andThen(callable $fn): Result`\n\nCalls `fn` if the result is `Ok`, otherwise returns the `Err` value of `self`.\n\nExample:\n\n```php\n$result = new Ok(42);\n$chained = $result-\u003eandThen(fn($value) =\u003e new Ok($value * 2));\necho $chained-\u003eunwrap(); // Output: 84\n\n$result = new Err(\"error\");\n$chained = $result-\u003eandThen(fn($value) =\u003e new Ok($value * 2));\necho $chained-\u003eunwrapErr(); // Output: \"error\"\n```\n\n#### `or(Result $res): Result`\n\nReturns `self` if it is `Ok`, otherwise returns `res`.\n\nExample:\n\n```php\n$result1 = new Ok(42);\n$result2 = new Ok(10);\n$combined = $result1-\u003eor($result2);\necho $combined-\u003eunwrap(); // Output: 42\n\n$result1 = new Err(\"error1\");\n$result2 = new Ok(10);\n$combined = $result1-\u003eor($result2);\necho $combined-\u003eunwrap(); // Output: 10\n```\n\n#### `orElse(callable $fn): Result`\n\nCalls `fn` if the result is `Err`, otherwise returns the `Ok` value of `self`.\n\nExample:\n\n```php\n$result = new Ok(42);\n$chained = $result-\u003eorElse(fn($error) =\u003e new Ok($error . \" handled\"));\necho $chained-\u003eunwrap(); // Output: 42\n\n$result = new Err(\"error\");\n$chained = $result-\u003eorElse(fn($error) =\u003e new Ok($error . \" handled\"));\necho $chained-\u003eunwrap(); // Output: \"error handled\"\n```\n\n#### `transpose(?string $noneClassName, ?string $someClassName): mixed`\n\nTransposes a `Result` of an `Option` into an `Option` of a `Result`.\n\nExample:\n\n```php\n$result = new Ok(new Some(42));\n$transposed = $result-\u003etranspose('\\Brimmar\\PhpOption\\None', '\\Brimmar\\PhpOption\\Some');\necho $transposed-\u003eunwrap()-\u003eunwrap(); // Output: 42\n\n$result = new Ok(new None());\n$transposed = $result-\u003etranspose('\\Brimmar\\PhpOption\\None', '\\Brimmar\\PhpOption\\Some');\necho $transposed-\u003eisNone(); // Output: true\n\n$result = new Err(\"error\");\n$transposed = $result-\u003etranspose('\\Brimmar\\PhpOption\\None', '\\Brimmar\\PhpOption\\Some');\necho $transposed-\u003eunwrap()-\u003eunwrapErr(); // Output: \"error\"\n```\n\n#### `match(callable $Ok, callable $Err): mixed`\n\nMatches the result and returns a value based on the provided patterns.\n\nExample:\n\n```php\n$result = new Ok(42);\n$value = $result-\u003ematch(\n    Ok: fn($value) =\u003e \"Success: $value\",\n    Err: fn($error) =\u003e \"Error: $error\"\n);\necho $value; // Output: \"Success: 42\"\n\n$result = new Err(\"error\");\n$value = $result-\u003ematch(\n    Ok: fn($value) =\u003e \"Success: $value\",\n    Err: fn($error) =\u003e \"Error: $error\"\n);\necho $value; // Output: \"Error: error\"\n```\n\n## Complementary Packages\n\nThis package works well with the PHP Option Type package, which implements the Option Type. Some methods in this package, such as transpose, depend on the Option Type implementation.\n\n[PhpOption](https://github.com/brimmar/phpoption/)\n\n## Static Analysis\n\nWe recommend using PHPStan for static code analysis. This package includes custom PHPStan rules to enhance type checking for Result types. To enable these rules, add the following to your PHPStan configuration:\n\n```sh\ncomposer require brimmar/phpstan-rustlike-result-extension --dev\n```\n\n```neon\n// phpstan.neon\nincludes:\n    - vendor/brimmar/phpstan-rustlike-result-extension/extension.neon\n```\n\n## Contributing\n\nPlease see CONTRIBUTING.md for details.\n\n## Security Vulnerabilities\n\nPleas review our security policy on how to report security vulnerabilities.\n\n## License\n\nPlease see LICENSE.md for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrimmar%2Fphpresult","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrimmar%2Fphpresult","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrimmar%2Fphpresult/lists"}