Commit 60d5c4ce authored by Nathan Harris's avatar Nathan Harris Committed by Nathan Harris

Add `fromRESP` label to `RESPValueConvertible.init`

Motivation:

During SSWG review, feedback was provided on the API design of the `RESPValueConvertible.init` signature and how it should appropriately follow Swift Design Guidelines regarding labels.

Modifications:

`RESPValueConvertible.init(_:` is now `RESPValueConvertible.init(fromRESP:)`.

Result:

There should be more clarity at the call site when initializing a type from a `RESPValue`.

This contributes to #47
parent f98b53e3
......@@ -217,7 +217,7 @@ extension RedisClient {
@inlinable
public func hget(_ field: String, from key: String) -> EventLoopFuture<String?> {
return send(command: "HGET", with: [key, field])
.map { return String($0) }
.map { return String(fromRESP: $0) }
}
/// Gets the values of a hash for the fields specified.
......
......@@ -379,7 +379,7 @@ extension RedisClient {
return send(command: command, with: args)
.flatMapThrowing {
guard !$0.isNull else { return nil }
guard let response = [RESPValue]($0) else {
guard let response = [RESPValue](fromRESP: $0) else {
throw RedisNIOError.responseConversion(to: [RESPValue].self)
}
assert(response.count == 2, "Unexpected response size returned!")
......
......@@ -30,7 +30,7 @@ extension RedisClient {
repeat {
let scoreItem = response[scoreIsFirst ? index : index + 1]
guard let score = Double(scoreItem) else {
guard let score = Double(fromRESP: scoreItem) else {
throw RedisNIOError.assertionFailure(message: "Unexpected response: '\(scoreItem)'")
}
......@@ -125,7 +125,7 @@ extension RedisClient {
@inlinable
public func zscore(of element: RESPValueConvertible, in key: String) -> EventLoopFuture<Double?> {
return send(command: "ZSCORE", with: [key, element])
.map { return Double($0) }
.map { return Double(fromRESP: $0) }
}
/// Incrementally iterates over all elements in a sorted set.
......@@ -420,13 +420,13 @@ extension RedisClient {
// or an array with 3 elements in the form [Set Key, Element Score, Element Value]
.flatMapThrowing {
guard !$0.isNull else { return nil }
guard let response = [RESPValue]($0) else {
guard let response = [RESPValue](fromRESP: $0) else {
throw RedisNIOError.responseConversion(to: [RESPValue].self)
}
assert(response.count == 3, "Unexpected response size returned!")
guard
let key = response[0].string,
let score = Double(response[1])
let score = Double(fromRESP: response[1])
else {
throw RedisNIOError.assertionFailure(message: "Unexpected structure in response: \(response)")
}
......
......@@ -25,10 +25,13 @@ extension EventLoopFuture where Value == RESPValue {
file: StaticString = #function,
function: StaticString = #function,
line: UInt = #line
) -> EventLoopFuture<T> where T: RESPValueConvertible
)
-> EventLoopFuture<T> where T: RESPValueConvertible
{
return self.flatMapThrowing {
guard let value = T($0) else { throw RedisNIOError.responseConversion(to: type) }
guard let value = T(fromRESP: $0) else {
throw RedisNIOError.responseConversion(to: type)
}
return value
}
}
......
......@@ -14,14 +14,14 @@
/// Capable of converting to / from `RESPValue`.
public protocol RESPValueConvertible {
init?(_ value: RESPValue)
init?(fromRESP value: RESPValue)
/// Creates a `RESPValue` representation.
func convertedToRESPValue() -> RESPValue
}
extension RESPValue: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
self = value
}
......@@ -32,7 +32,7 @@ extension RESPValue: RESPValueConvertible {
}
extension RedisError: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let error = value.error else { return nil }
self = error
}
......@@ -44,7 +44,7 @@ extension RedisError: RESPValueConvertible {
}
extension String: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let string = value.string else { return nil }
self = string
}
......@@ -56,7 +56,7 @@ extension String: RESPValueConvertible {
}
extension FixedWidthInteger {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
if let int = value.int {
self = Self(int)
} else {
......@@ -84,7 +84,7 @@ extension UInt32: RESPValueConvertible {}
extension UInt64: RESPValueConvertible {}
extension Double: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let string = value.string else { return nil }
guard let float = Double(string) else { return nil }
self = float
......@@ -97,7 +97,7 @@ extension Double: RESPValueConvertible {
}
extension Float: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let string = value.string else { return nil }
guard let float = Float(string) else { return nil }
self = float
......@@ -121,14 +121,14 @@ extension Collection where Element: RESPValueConvertible {
}
extension Array: RESPValueConvertible where Element: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let array = value.array else { return nil }
self = array.compactMap { Element($0) }
self = array.compactMap { Element(fromRESP: $0) }
}
}
extension ContiguousArray: RESPValueConvertible where Element: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let array = value.array else { return nil }
self = array.compactMap(Element.init).withUnsafeBytes {
.init(UnsafeRawBufferPointer($0).bindMemory(to: Element.self))
......@@ -137,9 +137,9 @@ extension ContiguousArray: RESPValueConvertible where Element: RESPValueConverti
}
extension Optional: RESPValueConvertible where Wrapped: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard !value.isNull else { return nil }
guard let wrapped = Wrapped(value) else { return nil }
guard let wrapped = Wrapped(fromRESP: value) else { return nil }
self = .some(wrapped)
}
......@@ -156,7 +156,7 @@ extension Optional: RESPValueConvertible where Wrapped: RESPValueConvertible {
import struct Foundation.Data
extension Data: RESPValueConvertible {
public init?(_ value: RESPValue) {
public init?(fromRESP value: RESPValue) {
guard let data = value.data else { return nil }
self = data
}
......
......@@ -127,7 +127,7 @@ final class HashCommandsTests: XCTestCase {
"second": "foo"
]
_ = try connection.hmset(dataset, in: #function).wait()
let values = try connection.hvals(in: #function).wait().compactMap { String($0) }
let values = try connection.hvals(in: #function).wait().compactMap { String(fromRESP: $0) }
XCTAssertEqual(values.count, 2)
XCTAssertTrue(values.allSatisfy(dataset.values.contains))
}
......
......@@ -48,7 +48,7 @@ final class ListCommandsTests: XCTestCase {
element = try connection.lindex(0, from: #function).wait()
XCTAssertFalse(element.isNull)
XCTAssertEqual(Int(element), 10)
XCTAssertEqual(Int(fromRESP: element), 10)
}
func test_lset() throws {
......@@ -56,7 +56,7 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.lpush([10], into: #function).wait()
XCTAssertNoThrow(try connection.lset(index: 0, to: 30, in: #function).wait())
let element = try connection.lindex(0, from: #function).wait()
XCTAssertEqual(Int(element), 30)
XCTAssertEqual(Int(fromRESP: element), 30)
}
func test_lrem() throws {
......@@ -75,8 +75,8 @@ final class ListCommandsTests: XCTestCase {
elements = try connection.lrange(within: (0, 4), from: #function).wait()
XCTAssertEqual(elements.count, 5)
XCTAssertEqual(Int(elements[0]), 1)
XCTAssertEqual(Int(elements[4]), 5)
XCTAssertEqual(Int(fromRESP: elements[0]), 1)
XCTAssertEqual(Int(fromRESP: elements[4]), 5)
elements = try connection.lrange(within: (2, 0), from: #function).wait()
XCTAssertEqual(elements.count, 0)
......@@ -93,12 +93,12 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.lpush([30], into: "second").wait()
var element = try connection.rpoplpush(from: "first", to: "second").wait()
XCTAssertEqual(Int(element), 10)
XCTAssertEqual(Int(fromRESP: element), 10)
XCTAssertEqual(try connection.llen(of: "first").wait(), 0)
XCTAssertEqual(try connection.llen(of: "second").wait(), 2)
element = try connection.rpoplpush(from: "second", to: "first").wait()
XCTAssertEqual(Int(element), 30)
XCTAssertEqual(Int(fromRESP: element), 30)
XCTAssertEqual(try connection.llen(of: "second").wait(), 1)
}
......@@ -106,7 +106,7 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.lpush([10], into: "first").wait()
let element = try connection.brpoplpush(from: "first", to: "second").wait() ?? .null
XCTAssertEqual(Int(element), 10)
XCTAssertEqual(Int(fromRESP: element), 10)
let blockingConnection = try Redis.makeConnection().wait()
let expectation = XCTestExpectation(description: "brpoplpush should never return")
......@@ -123,13 +123,13 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.linsert(20, into: #function, after: 10).wait()
var elements = try connection.lrange(within: (0, 1), from: #function)
.map { response in response.compactMap { Int($0) } }
.map { response in response.compactMap { Int(fromRESP: $0) } }
.wait()
XCTAssertEqual(elements, [10, 20])
_ = try connection.linsert(30, into: #function, before: 10).wait()
elements = try connection.lrange(within: (0, 2), from: #function)
.map { response in response.compactMap { Int($0) } }
.map { response in response.compactMap { Int(fromRESP: $0) } }
.wait()
XCTAssertEqual(elements, [30, 10, 20])
}
......@@ -142,7 +142,7 @@ final class ListCommandsTests: XCTestCase {
element = try connection.lpop(from: #function).wait()
XCTAssertFalse(element.isNull)
XCTAssertEqual(Int(element), 30)
XCTAssertEqual(Int(fromRESP: element), 30)
}
func test_blpop() throws {
......@@ -151,7 +151,7 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.lpush([10, 20, 30], into: "first").wait()
let pop1 = try connection.blpop(from: "first").wait() ?? .null
XCTAssertEqual(Int(pop1), 30)
XCTAssertEqual(Int(fromRESP: pop1), 30)
let pop2 = try connection.blpop(from: ["fake", "first"]).wait()
XCTAssertEqual(pop2?.0, "first")
......@@ -172,7 +172,7 @@ final class ListCommandsTests: XCTestCase {
let size = try connection.lpush([100], into: #function).wait()
let element = try connection.lindex(0, from: #function).wait()
XCTAssertEqual(size, 4)
XCTAssertEqual(Int(element), 100)
XCTAssertEqual(Int(fromRESP: element), 100)
}
func test_lpushx() throws {
......@@ -184,7 +184,7 @@ final class ListCommandsTests: XCTestCase {
size = try connection.lpushx(30, into: #function).wait()
XCTAssertEqual(size, 2)
let element = try connection.rpop(from: #function)
.map { return Int($0) }
.map { return Int(fromRESP: $0) }
.wait()
XCTAssertEqual(element, 10)
}
......@@ -194,7 +194,7 @@ final class ListCommandsTests: XCTestCase {
let element = try connection.rpop(from: #function).wait()
XCTAssertNotNil(element)
XCTAssertEqual(Int(element), 10)
XCTAssertEqual(Int(fromRESP: element), 10)
_ = try connection.delete([#function]).wait()
......@@ -208,7 +208,7 @@ final class ListCommandsTests: XCTestCase {
_ = try connection.lpush([10, 20, 30], into: "first").wait()
let pop1 = try connection.brpop(from: "first").wait() ?? .null
XCTAssertEqual(Int(pop1), 10)
XCTAssertEqual(Int(fromRESP: pop1), 10)
let pop2 = try connection.brpop(from: ["fake", "first"]).wait()
XCTAssertEqual(pop2?.0, "first")
......@@ -229,7 +229,7 @@ final class ListCommandsTests: XCTestCase {
let size = try connection.rpush([100], into: #function).wait()
let element = try connection.lindex(3, from: #function).wait()
XCTAssertEqual(size, 4)
XCTAssertEqual(Int(element), 100)
XCTAssertEqual(Int(fromRESP: element), 100)
}
func test_rpushx() throws {
......@@ -241,7 +241,7 @@ final class ListCommandsTests: XCTestCase {
size = try connection.rpushx(30, into: #function).wait()
XCTAssertEqual(size, 2)
let element = try connection.lpop(from: #function)
.map { return Int($0) }
.map { return Int(fromRESP: $0) }
.wait()
XCTAssertEqual(element, 10)
}
......
......@@ -259,7 +259,7 @@ final class SortedSetCommandsTests: XCTestCase {
XCTAssertEqual(elements.count, 6)
let values = try RedisConnection._mapSortedSetResponse(elements, scoreIsFirst: false)
.map { (value, _) in return Int(value) }
.map { (value, _) in return Int(fromRESP: value) }
XCTAssertEqual(values[0], 2)
XCTAssertEqual(values[1], 3)
......@@ -273,7 +273,7 @@ final class SortedSetCommandsTests: XCTestCase {
XCTAssertEqual(elements.count, 6)
let values = try RedisConnection._mapSortedSetResponse(elements, scoreIsFirst: false)
.map { (value, _) in return Int(value) }
.map { (value, _) in return Int(fromRESP: value) }
XCTAssertEqual(values[0], 9)
XCTAssertEqual(values[1], 8)
......@@ -313,14 +313,14 @@ final class SortedSetCommandsTests: XCTestCase {
var elements = try connection.zrangebylex(within: ("[1", "[2"), from: #function)
.wait()
.map { Int($0) }
.map { Int(fromRESP: $0) }
XCTAssertEqual(elements.count, 2)
XCTAssertEqual(elements[0], 1)
XCTAssertEqual(elements[1], 2)
elements = try connection.zrangebylex(within: ("[1", "(4"), from: #function, limitBy: (offset: 1, count: 1))
.wait()
.map { Int($0) }
.map { Int(fromRESP: $0) }
XCTAssertEqual(elements.count, 1)
XCTAssertEqual(elements[0], 2)
}
......@@ -330,14 +330,14 @@ final class SortedSetCommandsTests: XCTestCase {
var elements = try connection.zrevrangebylex(within: ("(2", "[4"), from: #function)
.wait()
.map { Int($0) }
.map { Int(fromRESP: $0) }
XCTAssertEqual(elements.count, 2)
XCTAssertEqual(elements[0], 4)
XCTAssertEqual(elements[1], 3)
elements = try connection.zrevrangebylex(within: ("[1", "(4"), from: #function, limitBy: (offset: 1, count: 2))
.wait()
.map { Int($0) }
.map { Int(fromRESP: $0) }
XCTAssertEqual(elements.count, 2)
XCTAssertEqual(elements[0], 2)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment