diff --git a/effect/_sync.py b/effect/_sync.py index 25d9b9f..73c7fb9 100644 --- a/effect/_sync.py +++ b/effect/_sync.py @@ -63,3 +63,28 @@ def sync_wrapper(*args): except: box.fail(sys.exc_info()) return sync_wrapper + + +def effect_performer(f): + """ + A decorator for performers that return effect + + The function being decorated is expected to take a dispatcher and an intent + (and not a box), and should return (dispatcher, effect) tuple. The returned + effect will be performed using returned dispatcher. + + Example:: + + @effect_performer + def perform_foo(dispatcher, foo): + new_disp = ComposedDispatcher( + [special_dispatcher(foo.fields), dispatcher]) + return new_disp, foo.effect + """ + @wraps(f) + def eff_wrapper(*args): + box = args[-1] + pass_args = args[:-1] + new_disp, eff = f(*pass_args) + perform(new_disp, eff, eff.on(box.succeed, box.fail)) + return eff_wrapper