Created
May 15, 2021 20:06
-
-
Save veber-alex/a4ada60012b270db0f0bbf481bbe4b28 to your computer and use it in GitHub Desktop.
Python Result type simulating Rust's Result enum.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Generic, Optional, TypeVar | |
from abc import ABC, abstractmethod | |
from dataclasses import dataclass | |
T = TypeVar('T') | |
E = TypeVar('E') | |
class Result(Generic[T, E], ABC): | |
@abstractmethod | |
def ok(self) -> Optional[T]: | |
pass | |
@abstractmethod | |
def err(self) -> Optional[E]: | |
pass | |
@dataclass | |
class Ok(Result[T, E]): | |
value: T | |
def ok(self) -> Optional[T]: | |
return self.value | |
def err(self) -> Optional[E]: | |
return None | |
@dataclass | |
class Err(Result[T, E]): | |
error: E | |
def ok(self) -> Optional[T]: | |
return None | |
def err(self) -> Optional[E]: | |
return self.error | |
def test(x: int) -> Result[int, str]: | |
if x > 10: | |
return Ok(x) | |
else: | |
return Err("error") | |
def main(): | |
if result := test(20).ok(): # same as `if let Ok(result) = test(20)` in Rust | |
print(result + 42) # the type checker knows result is `int` here | |
# New in 3.10 | |
match test(8): | |
case Ok(result): | |
print(result + 42) | |
case Err(e): | |
print(e + " :(") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment