Merge pull request #8 from Mordil/proposal-update

Update code to match current proposal
This commit is contained in:
Nathan Harris
2019-02-08 17:34:36 -08:00
committed by GitHub
7 changed files with 70 additions and 102 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ public final class RedisPipeline {
/// - arguments: The arguments, if any, to send with the command.
/// - Returns: A self-reference to this `RedisPipeline` instance for chaining commands.
@discardableResult
public func enqueue(command: String, arguments: [RESPConvertible] = []) throws -> RedisPipeline {
public func enqueue(command: String, arguments: [RESPValueConvertible] = []) throws -> RedisPipeline {
try _driverPipeline.enqueue(command: command, arguments: arguments)
return self
}
@@ -6,11 +6,11 @@ public struct RedisCommandContext {
/// A full command keyword and arguments stored as a single `RESPValue`.
public let command: RESPValue
/// A promise expected to be fulfilled with the `RESPValue` response to the command from Redis.
public let promise: EventLoopPromise<RESPValue>
public let responsePromise: EventLoopPromise<RESPValue>
public init(command: RESPValue, promise: EventLoopPromise<RESPValue>) {
self.command = command
self.promise = promise
self.responsePromise = promise
}
}
@@ -77,7 +77,7 @@ extension RedisCommandHandler: ChannelOutboundHandler {
/// See `ChannelOutboundHandler.write(ctx:data:promise:)`
public func write(ctx: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
let context = unwrapOutboundIn(data)
commandResponseQueue.insert(context.promise, at: 0)
commandResponseQueue.insert(context.responsePromise, at: 0)
ctx.write(wrapOutboundOut(context.command), promise: promise)
}
}
+59 -91
View File
@@ -1,143 +1,111 @@
import Foundation
/// Capable of converting to / from `RESPValue`.
public protocol RESPConvertible {
/// Create an instance of `Self` from `RESPValue`.
static func convertFromRESP(_ value: RESPValue) throws -> Self
public protocol RESPValueConvertible {
init?(_ value: RESPValue)
/// Convert self to `RESPValue`.
func convertToRESP() throws -> RESPValue
/// Creates a `RESPValue` representation.
func convertedToRESPValue() -> RESPValue
}
extension RESPValue: RESPConvertible {
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
extension RESPValue: RESPValueConvertible {
public init?(_ value: RESPValue) {
self = value
}
/// See `RESPValueConvertible`
public func convertedToRESPValue() -> RESPValue {
return self
}
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> RESPValue {
return value
}
}
extension String: RESPConvertible {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> String {
guard let string = value.string else {
throw RedisError(identifier: "string", reason: "Could not convert to string: \(value).")
}
return string
extension String: RESPValueConvertible {
public init?(_ value: RESPValue) {
guard let string = value.string else { return nil }
self = string
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
public func convertedToRESPValue() -> RESPValue {
return .bulkString(Data(self.utf8))
}
}
extension FixedWidthInteger {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> Self {
guard let int = value.int else {
guard let string = value.string else {
throw RedisError(identifier: "string", reason: "Could not convert to string: \(value)")
}
guard let int = Self(string) else {
throw RedisError(identifier: "int", reason: "Could not convert to int: \(value)")
}
return int
public init?(_ value: RESPValue) {
if let int = value.int {
self = Self(int)
} else {
guard let string = value.string else { return nil }
guard let int = Self(string) else { return nil }
self = Self(int)
}
return Self(int)
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
/// See `convertedToRESP`.
public func convertedToRESPValue() -> RESPValue {
return .bulkString(Data(self.description.utf8))
}
}
extension Int: RESPConvertible {}
extension Int8: RESPConvertible {}
extension Int16: RESPConvertible {}
extension Int32: RESPConvertible {}
extension Int64: RESPConvertible {}
extension UInt: RESPConvertible {}
extension UInt8: RESPConvertible {}
extension UInt16: RESPConvertible {}
extension UInt32: RESPConvertible {}
extension UInt64: RESPConvertible {}
extension Int: RESPValueConvertible {}
extension Int8: RESPValueConvertible {}
extension Int16: RESPValueConvertible {}
extension Int32: RESPValueConvertible {}
extension Int64: RESPValueConvertible {}
extension UInt: RESPValueConvertible {}
extension UInt8: RESPValueConvertible {}
extension UInt16: RESPValueConvertible {}
extension UInt32: RESPValueConvertible {}
extension UInt64: RESPValueConvertible {}
extension Double: RESPConvertible {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> Double {
guard let string = value.string else {
throw RedisError(identifier: "string", reason: "Could not convert to string: \(value).")
}
guard let float = Double(string) else {
throw RedisError(identifier: "double", reason: "Could not convert to double: \(value).")
}
return float
extension Double: RESPValueConvertible {
public init?(_ value: RESPValue) {
guard let string = value.string else { return nil }
guard let float = Double(string) else { return nil }
self = float
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
public func convertedToRESPValue() -> RESPValue {
return .bulkString(Data(self.description.utf8))
}
}
extension Float: RESPConvertible {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> Float {
guard let string = value.string else {
throw RedisError(identifier: "string", reason: "Could not convert to string: \(value).")
}
guard let float = Float(string) else {
throw RedisError(identifier: "float", reason: "Could not convert to float: \(value).")
}
return float
extension Float: RESPValueConvertible {
public init?(_ value: RESPValue) {
guard let string = value.string else { return nil }
guard let float = Float(string) else { return nil }
self = float
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
public func convertedToRESPValue() -> RESPValue {
return .bulkString(Data(self.description.utf8))
}
}
extension Data: RESPConvertible {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> Data {
guard let theData = value.data else {
throw RedisError(identifier: "data", reason: "Could not convert to data: \(value).")
}
return theData
extension Data: RESPValueConvertible {
public init?(_ value: RESPValue) {
guard let data = value.data else { return nil }
self = data
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
public func convertedToRESPValue() -> RESPValue {
return .bulkString(self)
}
}
extension Array: RESPConvertible where Element: RESPConvertible {
/// See `RESPValueConvertible`.
public static func convertFromRESP(_ value: RESPValue) throws -> Array<Element> {
guard let array = value.array else {
throw RedisError(identifier: "array", reason: "Could not convert to array: \(value).")
}
return try array.map { try Element.convertFromRESP($0) }
extension Array: RESPValueConvertible where Element: RESPValueConvertible {
public init?(_ value: RESPValue) {
guard let array = value.array else { return nil }
self = array.compactMap { Element($0) }
}
/// See `RESPValueConvertible`.
public func convertToRESP() throws -> RESPValue {
let dataArray = try map { try $0.convertToRESP() }
return RESPValue.array(dataArray)
public func convertedToRESPValue() -> RESPValue {
let elements = map { $0.convertedToRESPValue() }
return RESPValue.array(elements)
}
}
+2 -2
View File
@@ -42,8 +42,8 @@ public final class RedisConnection {
/// - command: The command to execute.
/// - arguments: The arguments to be sent with the command.
/// - Returns: An `EventLoopFuture` that will resolve with the Redis command response.
public func send(command: String, with arguments: [RESPConvertible] = []) throws -> EventLoopFuture<RESPValue> {
let args = try arguments.map { try $0.convertToRESP() }
public func send(command: String, with arguments: [RESPValueConvertible] = []) throws -> EventLoopFuture<RESPValue> {
let args = arguments.map { $0.convertedToRESPValue() }
return self.command(command, arguments: args)
}
+2 -2
View File
@@ -38,8 +38,8 @@ public final class RedisPipeline {
/// - arguments: The arguments, if any, to send with the command.
/// - Returns: A self-reference for chaining commands.
@discardableResult
public func enqueue(command: String, arguments: [RESPConvertible] = []) throws -> RedisPipeline {
let args = try arguments.map { try $0.convertToRESP() }
public func enqueue(command: String, arguments: [RESPValueConvertible] = []) throws -> RedisPipeline {
let args = arguments.map { $0.convertedToRESPValue() }
let promise = channel.eventLoop.makePromise(of: RESPValue.self)
let context = RedisCommandContext(
+1 -1
View File
@@ -29,7 +29,7 @@ final class RedisDriverTests: XCTestCase {
func test_command_succeeds() throws {
let result = try connection.command(
"SADD",
arguments: [.bulkString("key".convertedToData()), try 3.convertToRESP()
arguments: [.bulkString("key".convertedToData()), 3.convertedToRESPValue()
]).wait()
XCTAssertNotNil(result.int)
+2 -2
View File
@@ -3,7 +3,7 @@ version: 2
jobs:
linux:
docker:
- image: codevapor/swift:5.0
- image: vapor/swift:5.0
- image: redis:5
steps:
- checkout
@@ -11,7 +11,7 @@ jobs:
- run: swift test
linux-release:
docker:
- image: codevapor/swift:5.0
- image: vapor/swift:5.0
steps:
- checkout
- run: swift build -c release