rustshed


Namerustshed JSON
Version 0.5.0 PyPI version JSON
download
home_pagehttps://github.com/pawelrubin/rustshed
SummaryRust types in Python.
upload_time2022-12-22 18:37:55
maintainer
docs_urlNone
authorPaweł Rubin
requires_python>=3.10,<4.0
licenseMIT
keywords rust result option
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # rustshed

[![Python 3.10](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/release/python-3100/)
[![codecov](https://codecov.io/gh/pawelrubin/rustshed/branch/main/graph/badge.svg?token=LV5XXHDSF5)](https://codecov.io/gh/pawelrubin/rustshed)
[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/pawelrubin/rustshed/blob/main/LICENSE)

A collection of Rust types in Python with complete type annotations.

### Supported Types

- Option
- Result

## Install

```shell
pip install rustshed
```


## Examples

### Option

The `Option` type represents an optional value: every `Option[T]` is either `Some[T]` and contains a value of type `T`, or `Null` (`None` in Rust), and does not.

```Python
from typing import SupportsIndex, TypeVar

from rustshed import Null, Option, Some

T = TypeVar("T")


class SafeList(list[T]):
    def get(self, index: SupportsIndex) -> Option[T]:
        try:
            return Some(self[index])
        except IndexError:
            return Null

a_list = SafeList([2, 1, 3, 7])
print(a_list.get(1))  # Some(value=1)
print(a_list.get(420))  # Null
```

### Result

The `Result` is the type used for returning and propagating errors: every `Result[T, E]` is either `Ok[T]`, representing success and containing a value of type `T`, or `Err[E]`, representing failure and containing an error of type `E`.

```python
from rustshed import to_result, Result


@to_result[ValueError]
def parse(x: str) -> int:
    return int(x)


def multiply(a: str, b: str) -> Result[int, str]:
    # try to parse two strings and multiply them
    # map a possible error to str
    return parse(a).and_then(lambda n: parse(b).map(lambda m: n * m)).map_err(str)


print(multiply("21", "2"))  # Ok(value=42)
print(multiply("2!", "2"))  # Err(error="invalid literal for int() with base 10: '2!'")
```

### Rust's question mark (?) operator

The question mark (`?`) operator in Rust hides some of the boilerplate of propagating errors up the call stack. Implementing this operator in Python would require changes to the language grammar, hence in **rustshed** it had to be implemented differently.

### Q property

The question mark's functionality has been implemented via the `Q` property (for both `Option` and `Result` types) combined with the `rustshed.result_shortcut` or `rustshed.option_shortcut` decorator.


```python
from rustshed import Ok, Result, to_result, result_shortcut


@to_result[ValueError]
def parse(x: str) -> int:
    return int(x)


# explicit early error return with match statements
def try_to_parse_early_return(a: str, b: str) -> Result[int, ValueError]:
    match parse(a):
        case Ok(value):
            x = value
        case err:
            return err

    match parse(b):
        case Ok(value):
            y = value
        case err:
            return err

    return Ok(x + y)


# early error return using the Q property
@result_shortcut
def try_to_parse(a: str, b: str) -> Result[int, ValueError]:
    x = parse(a).Q
    y = parse(b).Q
    return Ok(x + y)

```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/pawelrubin/rustshed",
    "name": "rustshed",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10,<4.0",
    "maintainer_email": "",
    "keywords": "rust,result,option",
    "author": "Pawe\u0142 Rubin",
    "author_email": "pawelrubindev@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/76/63/b262eb6219e6a175c55a4e56c13a056d0d1397e4546c34206ac3104667d1/rustshed-0.5.0.tar.gz",
    "platform": null,
    "description": "# rustshed\n\n[![Python 3.10](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/release/python-3100/)\n[![codecov](https://codecov.io/gh/pawelrubin/rustshed/branch/main/graph/badge.svg?token=LV5XXHDSF5)](https://codecov.io/gh/pawelrubin/rustshed)\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/pawelrubin/rustshed/blob/main/LICENSE)\n\nA collection of Rust types in Python with complete type annotations.\n\n### Supported Types\n\n- Option\n- Result\n\n## Install\n\n```shell\npip install rustshed\n```\n\n\n## Examples\n\n### Option\n\nThe `Option` type represents an optional value: every `Option[T]` is either `Some[T]` and contains a value of type `T`, or `Null` (`None` in Rust), and does not.\n\n```Python\nfrom typing import SupportsIndex, TypeVar\n\nfrom rustshed import Null, Option, Some\n\nT = TypeVar(\"T\")\n\n\nclass SafeList(list[T]):\n    def get(self, index: SupportsIndex) -> Option[T]:\n        try:\n            return Some(self[index])\n        except IndexError:\n            return Null\n\na_list = SafeList([2, 1, 3, 7])\nprint(a_list.get(1))  # Some(value=1)\nprint(a_list.get(420))  # Null\n```\n\n### Result\n\nThe `Result` is the type used for returning and propagating errors: every `Result[T, E]` is either `Ok[T]`, representing success and containing a value of type `T`, or `Err[E]`, representing failure and containing an error of type `E`.\n\n```python\nfrom rustshed import to_result, Result\n\n\n@to_result[ValueError]\ndef parse(x: str) -> int:\n    return int(x)\n\n\ndef multiply(a: str, b: str) -> Result[int, str]:\n    # try to parse two strings and multiply them\n    # map a possible error to str\n    return parse(a).and_then(lambda n: parse(b).map(lambda m: n * m)).map_err(str)\n\n\nprint(multiply(\"21\", \"2\"))  # Ok(value=42)\nprint(multiply(\"2!\", \"2\"))  # Err(error=\"invalid literal for int() with base 10: '2!'\")\n```\n\n### Rust's question mark (?) operator\n\nThe question mark (`?`) operator in Rust hides some of the boilerplate of propagating errors up the call stack. Implementing this operator in Python would require changes to the language grammar, hence in **rustshed** it had to be implemented differently.\n\n### Q property\n\nThe question mark's functionality has been implemented via the `Q` property (for both `Option` and `Result` types) combined with the `rustshed.result_shortcut` or `rustshed.option_shortcut` decorator.\n\n\n```python\nfrom rustshed import Ok, Result, to_result, result_shortcut\n\n\n@to_result[ValueError]\ndef parse(x: str) -> int:\n    return int(x)\n\n\n# explicit early error return with match statements\ndef try_to_parse_early_return(a: str, b: str) -> Result[int, ValueError]:\n    match parse(a):\n        case Ok(value):\n            x = value\n        case err:\n            return err\n\n    match parse(b):\n        case Ok(value):\n            y = value\n        case err:\n            return err\n\n    return Ok(x + y)\n\n\n# early error return using the Q property\n@result_shortcut\ndef try_to_parse(a: str, b: str) -> Result[int, ValueError]:\n    x = parse(a).Q\n    y = parse(b).Q\n    return Ok(x + y)\n\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Rust types in Python.",
    "version": "0.5.0",
    "split_keywords": [
        "rust",
        "result",
        "option"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "162806cf37398aacce25c5dcc405ca70",
                "sha256": "90545bc8a32fc46cbe93cdddc659c1b51cca0eba65863c90dbc31e0fdd1012c6"
            },
            "downloads": -1,
            "filename": "rustshed-0.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "162806cf37398aacce25c5dcc405ca70",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10,<4.0",
            "size": 10955,
            "upload_time": "2022-12-22T18:37:54",
            "upload_time_iso_8601": "2022-12-22T18:37:54.105299Z",
            "url": "https://files.pythonhosted.org/packages/17/44/97759d5a1d604aab464f4f90f0f21cc9c801f66fda175616505a14ce50dd/rustshed-0.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "c82cd22aa163aae2ad9513fc498c8caa",
                "sha256": "27bf1da6ee635864e94cdea83b2d514562585c28b5a94b3829e45952b6de4bf9"
            },
            "downloads": -1,
            "filename": "rustshed-0.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c82cd22aa163aae2ad9513fc498c8caa",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10,<4.0",
            "size": 10251,
            "upload_time": "2022-12-22T18:37:55",
            "upload_time_iso_8601": "2022-12-22T18:37:55.677463Z",
            "url": "https://files.pythonhosted.org/packages/76/63/b262eb6219e6a175c55a4e56c13a056d0d1397e4546c34206ac3104667d1/rustshed-0.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-22 18:37:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "pawelrubin",
    "github_project": "rustshed",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "rustshed"
}
        
Elapsed time: 0.05592s