diff --git a/pyresult/operators.py b/pyresult/operators.py index ed21d2b..b109910 100644 --- a/pyresult/operators.py +++ b/pyresult/operators.py @@ -4,7 +4,6 @@ from toolz import curry from pyresult.result import ( - VALUE_IDX, ok, error, result, @@ -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 @@ -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 @@ -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 @@ -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 @@ -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) @@ -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) diff --git a/pyresult/result.py b/pyresult/result.py index 09dc5b4..b9cb3f7 100644 --- a/pyresult/result.py +++ b/pyresult/result.py @@ -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): @@ -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 diff --git a/tests/test_result.py b/tests/test_result.py index aa24e5a..7fc3a02 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -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(): @@ -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():