# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['orz']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'orz',
    'version': '0.3.1',
    'description': 'A Result(Either) like library to handle error fluently',
    'long_description': "**orz**: Result type\n=============================\n\n**orz** aims to provide a more pythonic and mature Result type(or similar to Result type) for Python.\n\nResult is a Monad type for handling success response and errors without using `try ... except` or special values(e.g. `-1`, `0` or `None`). It makes your code more readable and more elegant.\n\nMany langauges already have a builtin Result type. e.g. `Result in Rust <https://doc.rust-lang.org/std/result/>`_, `Either type in Haskell <http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Either.html>`_ , `Result type in Swift <https://developer.apple.com/documentation/swift/result>`_ and `Result type in OCaml <https://ocaml.org/learn/tutorials/error_handling.html#Resulttype>`_. And there's a `proposal in Go <https://github.com/golang/go/issues/19991>`_. Although `Promise in Javascript <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_ is not a Result type, it handles errors fluently in a similar way.\n\nExisting Result type Python libraries, such as `dbrgn/result <https://github.com/dbrgn/result>`_, `arcrose/result_py <https://github.com/arcrose/result_py>`_, and `ipconfiger/result2 <https://github.com/ipconfiger/result2>`_ did great job on porting Result from other languages. However, most of these libraries doesn't support Python 2(sadly, I still have to use it). And because of the syntax limitation of Python, like lack of pattern matching, it's not easy to show all the strength of Result type.\n\n**orz** trying to make Result more pythonic and readable, useful in most cases.\n\nInstall Orz\n=============\n\nJust like other Python package, install it by `pip\n<https://pip.pypa.io/en/stable/>`_ into a `virtualenv\n<https://hynek.me/articles/virtualenv-lives/>`_, or use `poetry\n<https://poetry.eustace.io/>`_ to automatically create and manage the\nvirtualenv.\n\n.. code-block:: console\n\n   $ pip install orz\n\nGetting Start\n=============\n\nCreate a ``orz.Result`` object\n------------------------------\n\nWrap the return value with ``orz.Ok`` explicitly for indicating success. And\nreturn an ``orz.Err`` object when something went wrong. Normally, the value wraped with\n``Err`` is an error message or an exception object.\n\n.. code-block:: python\n\n   >>> import orz\n\n   >>> def get_score_rz(subj):\n   ...     score_db = {'math': 80, 'physics': 95}\n   ...     if subj in score_db:\n   ...         return orz.Ok(score_db[subj])\n   ...     else:\n   ...         return orz.Err('subj does not exist: ' + subj)\n\n   >>> get_score_rz('math')\n   Ok(80)\n   >>> get_score_rz('bio')\n   Err('subj does not exist: bio')\n\nA handy decorator ``orz.catch`` can transform normal function into a\nResult-oriented function. The return value would be wraped with ``orz.Ok``\nautomatically, and exceptions would be captured and wraped with ``orz.Err``.\n\n.. code-block:: python\n\n   >>> @orz.catch(raises=KeyError)\n   ... def get_score_rz(subj):\n   ...     score_db = {'math': 80, 'physics': 95}\n   ...     return score_db[subj]\n\n   >>> get_score_rz('math')\n   Ok(80)\n   >>> get_score_rz('bio')\n   Err(KeyError('bio',))\n\nProcessing Pipeline\n-------------------\n\nBoth ``Ok`` and ``Err`` are of ``Result`` type, they have the same set of methods for further processing. The value in ``Ok`` would be transformed with ``then(func)``. And ``Err`` would skip the transformation, and propogate the error to the next stage.\n\n.. code-block:: python\n\n   >>> def get_letter_grade_rz(score):\n   ...     if 90 <= score <= 100: return orz.Ok('A')\n   ...     elif 80 <= score < 90: return orz.Ok('B')\n   ...     elif 70 <= score < 80: return orz.Ok('C')\n   ...     elif 60 <= score < 70: return orz.Ok('D')\n   ...     elif 0 <= score <= 60: return orz.Ok('F')\n   ...     else: return orz.Err('Wrong value range')\n\n   >>> get_score_rz('math')\n   Ok(80)\n   >>> get_score_rz('math').then(get_letter_grade_rz)\n   Ok('B')\n   >>> get_score_rz('bio')\n   Err(KeyError('bio',))\n   >>> get_score_rz('bio').then(get_letter_grade_rz)\n   Err(KeyError('bio',))\n\n\nThe ``func`` pass to the ``then(func, catch_raises=None)`` can be a normal\nfunction which returns an ordinary value. The returned value would be wraped with\n``Ok`` automatically. Use ``catch_raises`` to capture exceptions and returned as an ``Err`` object.\n\n.. code-block:: python\n\n   >>> letter_grade_rz = get_score_rz('math').then(get_letter_grade_rz)\n   >>> msg_rz = letter_grade_rz.then(lambda letter_grade: 'your grade is {}'.format(letter_grade))\n   >>> msg_rz\n   Ok('your grade is B')\n\nConnect all the ``then(func)`` calls together. And use\n``Result.get_or(default)`` to get the final\nvalue.\n\n.. code-block:: python\n\n   >>> def get_grade_msg(subj):\n   ...      return (\n   ...          get_score_rz(subj)\n   ...          .then(get_letter_grade_rz)\n   ...          .then(lambda letter_grade: 'your grade is {}'.format(letter_grade))\n   ...          .get_or('something went wrong'))\n\n   >>> get_grade_msg('math')\n   'your grade is B'\n   >>> get_grade_msg('bio')\n   'something went wrong'\n\nIf you prefer to raise an exception rather than get a fallback value, use ``get_or_raise(error)`` instead.\n\n.. code-block:: python\n\n   >>> def get_grade_msg(subj):\n   ...      return (\n   ...          get_score_rz(subj)\n   ...          .then(get_letter_grade_rz)\n   ...          .then(lambda letter_grade: 'your grade is {}'.format(letter_grade))\n   ...          .get_or_raise())\n\n   >>> get_grade_msg('math')\n   'your grade is B'\n   >>> get_grade_msg('bio')\n   Traceback (most recent call last):\n   ...\n   KeyError: 'bio'\n\n\nHandling Error\n--------------\n\nUse ``Result.err_then(func, catch_raises)`` to convert ``Err`` back to ``Ok`` or to other ``Err``.\n\n.. code-block:: python\n\n   >>> get_score_rz('bio')\n   Err(KeyError('bio',))\n   >>> get_score_rz('bio').then(get_letter_grade_rz)\n   Err(KeyError('bio',))\n   >>> (get_score_rz('bio')\n   ...  .err_then(lambda error: 0 if isinstance(error, KeyError) else error))\n   Ok(0)\n   >>> (get_score_rz('bio')\n   ...  .err_then(lambda error: 0 if isinstance(error, KeyError) else error)\n   ...  .then(get_letter_grade_rz))\n   Ok('F')\n   >>> (get_score_rz('bio')\n   ...  .then(get_letter_grade_rz)\n   ...  .err_then(lambda error: 'F' if isinstance(error, KeyError) else error))\n   Ok('F')\n\n\nMost of the time, ``fill()`` is more concise to turn some ``Err`` back.\n\n.. code-block:: python\n\n   >>> get_score_rz('bio').fill(lambda error: isinstance(error, KeyError), 0)\n   Ok(0)\n\n\nMore in Orz\n===========\n\nProcess Multiple Result objects\n-------------------------------\n\nTo ensure all values are ``Ok`` and handle them together.\n\n.. code-block:: python\n\n   >>> orz.all([orz.Ok(39), orz.Ok(2), orz.Ok(1)])\n   Ok([39, 2, 1])\n   >>> orz.all([orz.Ok(40), orz.Err('wrong value'), orz.Ok(1)])\n   Err('wrong value')\n\n   >>> orz.all([orz.Ok(40), orz.Ok(2)]).then(lambda values: sum(values))\n   Ok(42)\n   >>> orz.all([orz.Ok(40), orz.Ok(2)]).then_unpack(lambda n1, n2: n1 + n2)\n   Ok(42)\n\n\n``then_all()`` is useful when you want to apply multiple functions to the same value.\n\n.. code-block:: python\n\n   >>> orz.Ok(3).then_all(lambda n: n+2, lambda n: n+1)\n   Ok([5, 4])\n   >>> orz.Ok(3).then_all(lambda n: n+2, lambda n: n+1).then_unpack(lambda n1, n2: n1 + n2)\n   Ok(9)\n\nUse ``first_ok()`` To get the first available value.\n\n.. code-block:: python\n\n   >>> orz.first_ok([orz.Err('E1'), orz.Ok(42), orz.Ok(3)])\n   Ok(42)\n   >>> orz.first_ok([orz.Err('E1'), orz.Err('E2'), orz.Err('E3')])\n   Err('E3')\n   >>> orz.Ok(15).then_first_ok(\n   ...     lambda v: 2 if (v % 2) == 0 else orz.Err('not a factor'),\n   ...     lambda v: 3 if (v % 3) == 0 else orz.Err('not a factor'),\n   ...     lambda v: 5 if (v % 5) == 0 else orz.Err('not a factor'))\n   Ok(3)\n\nGuard value\n-----------\n\n.. code-block:: python\n\n   >>> orz.Ok(3).guard(lambda v: v > 0)\n   Ok(3)\n   >>> orz.Ok(-3).guard(lambda v: v > 0)\n   Err(CheckError('Ok(-3) was failed to pass the guard: <function <lambda> at ...>',))\n   >>> orz.Ok(-3).guard(lambda v: v > 0, err=orz.Err('value should be greater than zero'))\n   Err('value should be greater than zero')\n\nIn fact, guard is a short-hand for a pattern of ``then()``.\n\n.. code-block:: python\n\n   >>> (orz.Ok(-3)\n   ...  .then(lambda v:\n   ...        orz.Ok(v) if v > 0\n   ...        else orz.Err('value should be greater than zero')))\n   Err('value should be greater than zero')\n\n   >>> orz.Ok(3).guard_none()\n   Ok(3)\n   >>> orz.Ok(None).guard_none()\n   Err(CheckError('failed to pass not None guard: ...',))\n\nConvert any value to Result type\n--------------------------------\n\n``orz.ensure`` always returns a Result object.\n\n.. code-block:: python\n\n   >>> orz.ensure(42)\n   Ok(42)\n   >>> orz.ensure(orz.Ok(42))\n   Ok(42)\n   >>> orz.ensure(orz.Ok(orz.Ok(42)))\n   Ok(42)\n   >>> orz.ensure(orz.Err('failed'))\n   Err('failed')\n   >>> orz.ensure(KeyError('a'))\n   Err(KeyError('a',))\n\n\nCheck if object is a Result\n----------------------------\n\n.. code-block:: python\n\n   >>> orz.is_result(orz.Ok(3))\n   True\n   >>> isinstance(orz.Ok(3), orz.Result)\n   True\n   >>> orz.Ok(3).is_ok()\n   True\n   >>> orz.Ok(3).is_err()\n   False\n   >>> orz.Err('E').is_ok()\n   False\n   >>> orz.Err('E').is_err()\n   True\n",
    'author': 'Yen, Tzu-Hsi',
    'author_email': 'joseph.yen@gmail.com',
    'url': 'https://github.com/d2207197/orz',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
}


setup(**setup_kwargs)
