Home > Software design >  Is it possible to transform a future type?
Is it possible to transform a future type?

Time:10-08

Using a library that has a method like this one:

std::future<bool> action();

I find my self in a situation where I have to conform with project specific enum return types like:

enum Result { Ok, Failed, ConnectionDown, ServerError };

and the call site of action looks like this:

std::future<Result> act()
{
  try {
    return _actor->action(); // This returns a different type :(
    // What to do here ??? ^
  } 
  catch (ConnectionError const& e)
  {
    return std::make_ready_future<Result>(Result::ConnectionError);
  }
  catch (ServerError const& e)
  {
    return std::make_ready_future<Result>(Result::ServerError);
  }
}

so essentially the library doesn't have specific return codes for error cases, they are rather emitted as exceptions. Handling that is easy because I can construct ready futures with the appropriate value. The problem (ironically) is with the non exceptional path, where the library's std::future<bool> has to be transformed to std::future<Result>.

It's pointless to .get() the result and construct a ready future based on its value (true -> Ok, false -> Failed) because this way I'm removing asynchronicity from my function. Is there a better way to handle this?

CodePudding user response:

Waiting for continuation function (std::experimental::future::then) , you probably want something like:

std::future<Result> act()
{
    return std::async([&](){
        try {
            if (_actor->action().get()) {
                return Result::Ok;
            } else {
                return Result::Failed;
            }
        } 
        catch (ConnectionError const& e) {
            return Result::ConnectionError;
        }
        catch (ServerError const& e) {
            return Result::ServerError;
        }
    });
}
  • Related