SwiftNIO Redis Client

One thing that I still haven't quite figured out - and am open to ideas - is how to easily support both SwiftNIO contexts (EventLoopFutures) and Dispatch (callbacks) without duplicating code or having both mixed in code completion tools.

As brought up in the NIOPostgres Pitch the ideal is that when working with NIORedis you see code completion with functions that return EventLoopFuture while DispatchRedis has callback parameters.

When working in one context, the noise of the other should be removed.

My pass at this was to use NIORedis under the hood of DispatchRedis (names are in flux)

public final class Redis {
    private let driver: RedisDriver

    deinit { try? driver.terminate() }

    public init(threadCount: Int = 1) { /* initialize RedisDriver */ }

    public func makeConnection(
        hostname: String,
        port: Int, password: String?,
        queue: DispatchQueue, 
        _: @escaping (Result<RedisConnection, Error>) -> Void)

But this breaks down of being able to allow "arbitrary" initialization for RedisConnection, as it needs the NIORedis.RedisConnection to act as a "driver". Users will now be made aware of NIORedis as an implementation detail.