Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions pyresult/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from toolz import curry

from pyresult.result import (
VALUE_IDX,
ok,
error,
result,
Expand All @@ -19,7 +18,8 @@ def errmap(func, res):

errmap: (x -> y) -> Result a x -> Result a y
'''
return error(func(res[VALUE_IDX])) if is_error(res) else res
res = result(res)
return error(func(res.value)) if is_error(res) else res


@curry
Expand All @@ -28,7 +28,8 @@ def rmap(func, res):

rmap: (a -> value) -> Result a -> Result value
'''
return ok(func(res[VALUE_IDX])) if is_ok(res) else res
res = result(res)
return ok(func(res.value)) if is_ok(res) else res


@curry
Expand All @@ -37,7 +38,8 @@ def and_then(func, res):

and_then: (a -> Result b x) -> Result a x -> Result b x
'''
return result(func(res[VALUE_IDX])) if is_ok(res) else res
res = result(res)
return result(func(res.value)) if is_ok(res) else res


@curry
Expand All @@ -46,7 +48,8 @@ def and_else(func, res):

and_else: (x -> Result b x) -> Result a x -> Result a x
'''
return result(func(res[VALUE_IDX])) if is_error(res) else res
res = result(res)
return result(func(res.value)) if is_error(res) else res


@curry
Expand All @@ -61,10 +64,11 @@ def fold(res):
err = [None]*len_res

for i, e in enumerate(res):
e = result(e)
if is_ok(e):
val[i] = e[VALUE_IDX]
val[i] = e.value
else:
err[i] = e[VALUE_IDX]
err[i] = e.value

if None in val:
return error(err)
Expand All @@ -77,4 +81,5 @@ def resolve(res):

resolve: Result (Result a x) x -> Result a x
'''
return res if is_error(res) else result(res[VALUE_IDX])
res = result(res)
return res if is_error(res) else result(res.value)
24 changes: 13 additions & 11 deletions pyresult/result.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
'''Result pattern implementation'''

import collections

OK = 'Ok'
ERROR = 'Error'

STATUS_IDX = 0
VALUE_IDX = 1
Result = collections.namedtuple('Result', ('status', 'value'))


class ResultError(Exception):
Expand All @@ -16,37 +16,39 @@ class ResultError(Exception):

def ok(val): # pylint: disable=invalid-name
'''Create Ok result'''
return (OK, val)
return Result(OK, val)


def error(msg):
'''Create error result'''
return (ERROR, msg)
return Result(ERROR, msg)


def result(res):
'''Check value is result'''
if not isinstance(res, tuple) or len(res) != 2:
raise ResultError(u'Error: Value \'{0}\' isn\'t 2-tuple.'.format(res))
if res[STATUS_IDX] != OK and res[STATUS_IDX] != ERROR:
raise ResultError(u'Error: Value \'{0!r}\' isn\'t 2-tuple.'.format(res))
res = Result(*res)
if res.status != OK and res.status != ERROR:
raise ResultError(
u'Error: Value \'{0}\' isn\'t \'Ok\' or \'Error\'.'.format(res)
u'Error: Value \'{0!r}\' isn\'t \'Ok\' or \'Error\'.'.format(res)
)
return res


def is_ok(res):
'''Check result is Ok'''
return result(res)[STATUS_IDX] == OK
return result(res).status == OK


def is_error(res):
'''Check result is Error'''
return result(res)[STATUS_IDX] == ERROR
return result(res).status == ERROR


def value(res):
'''Return stored value in Result'''
res = result(res)
if is_error(res):
raise ResultError(res[VALUE_IDX])
return res[VALUE_IDX]
raise ResultError(res.value)
return res.value
4 changes: 2 additions & 2 deletions tests/test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_result_ok_tuple():

def test_result_ok_2tuple():
with pytest.raises(ResultError):
result((OK))
result((OK,))


def test_result_error_tuple():
Expand All @@ -55,7 +55,7 @@ def test_result_error_tuple():

def test_result_error_2tuple():
with pytest.raises(ResultError):
result((ERROR))
result((ERROR,))


def test_result_isnt_ok_either_error():
Expand Down