Rename ELF extension `map` to `tryConverting` and make internal

Motivation:

As originally pointed out in #48, the `map` prefix alone is not enough context into what the method actually does.

Since it fails the future, and isn't a mapping function, the name should reflect this.

But, this method as-is currently provides little value outside of the client context, so it should not be `public`.

If users provide an adequate use case for having it outside of the package, then it can be made public again.

Modifications:

- Rename: ELF where Value == RESPValue extension `map` to `tryConverting`
- Change: `tryConverting` from public to internal

Result:

A "problematic" method should no longer be available for API users to hurt themselves with.
parent 8b75ef7f
Pipeline #173235489 passed with stage
in 0 seconds
......@@ -23,7 +23,7 @@ extension RedisClient {
public func echo(_ message: String) -> EventLoopFuture<String> {
let args = [RESPValue(bulk: message)]
return send(command: "ECHO", with: args)
.map()
.tryConverting()
}
/// Pings the server, which will respond with a message.
......@@ -36,7 +36,7 @@ extension RedisClient {
? [.init(bulk: message!)] // safe because we did a nil pre-check
: []
return send(command: "PING", with: args)
.map()
.tryConverting()
}
/// Select the Redis logical database having the specified zero-based numeric index.
......@@ -64,7 +64,7 @@ extension RedisClient {
.init(bulk: second)
]
return send(command: "SWAPDB", with: args)
.map(to: String.self)
.tryConverting(to: String.self)
.map { return $0 == "OK" }
}
......@@ -89,7 +89,7 @@ extension RedisClient {
let args = keys.map(RESPValue.init)
return send(command: "DEL", with: args)
.map()
.tryConverting()
}
/// Removes the specified keys. A key is ignored if it does not exist.
......@@ -111,7 +111,7 @@ extension RedisClient {
RESPValue(from: $0)
}
return self.send(command: "EXISTS", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
}
/// Checks the existence of the provided keys in the database.
......@@ -137,7 +137,7 @@ extension RedisClient {
.init(bulk: timeout.seconds)
]
return send(command: "EXPIRE", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
}
......@@ -153,7 +153,7 @@ extension RedisClient {
public func ttl(_ key: RedisKey) -> EventLoopFuture<RedisKeyLifetime> {
let args: [RESPValue] = [RESPValue(from: key)]
return self.send(command: "TTL", with: args)
.map(to: Int64.self)
.tryConverting(to: Int64.self)
.map { RedisKeyLifetime(seconds: $0) }
}
......@@ -165,7 +165,7 @@ extension RedisClient {
public func pttl(_ key: RedisKey) -> EventLoopFuture<RedisKeyLifetime> {
let args: [RESPValue] = [RESPValue(from: key)]
return self.send(command: "PTTL", with: args)
.map(to: Int64.self)
.tryConverting(to: Int64.self)
.map { RedisKeyLifetime(milliseconds: $0) }
}
}
......@@ -287,7 +287,7 @@ extension RedisClient {
args.append(.init(bulk: c))
}
let response = send(command: command, with: args).map(to: [RESPValue].self)
let response = send(command: command, with: args).tryConverting(to: [RESPValue].self)
let position = response.flatMapThrowing { result -> Int in
guard
let value = result[0].string,
......@@ -299,7 +299,7 @@ extension RedisClient {
}
let elements = response
.map { return $0[1] }
.map(to: resultType)
.tryConverting(to: resultType)
return position.and(elements)
}
......
......@@ -56,7 +56,7 @@ extension RedisClient {
args.append(convertingContentsOf: fields)
return send(command: "HDEL", with: args)
.map()
.tryConverting()
}
/// Removes the specified fields from a hash.
......@@ -83,7 +83,7 @@ extension RedisClient {
.init(bulk: field)
]
return send(command: "HEXISTS", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
......@@ -95,7 +95,7 @@ extension RedisClient {
public func hlen(of key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "HLEN", with: args)
.map()
.tryConverting()
}
/// Gets the string length of a hash field's value.
......@@ -111,7 +111,7 @@ extension RedisClient {
.init(bulk: field)
]
return send(command: "HSTRLEN", with: args)
.map()
.tryConverting()
}
/// Gets all field names in a hash.
......@@ -122,7 +122,7 @@ extension RedisClient {
public func hkeys(in key: RedisKey) -> EventLoopFuture<[String]> {
let args = [RESPValue(from: key)]
return send(command: "HKEYS", with: args)
.map()
.tryConverting()
}
/// Gets all values stored in a hash.
......@@ -133,7 +133,7 @@ extension RedisClient {
public func hvals(in key: RedisKey) -> EventLoopFuture<[RESPValue]> {
let args = [RESPValue(from: key)]
return send(command: "HVALS", with: args)
.map()
.tryConverting()
}
/// Gets all values stored in a hash.
......@@ -221,7 +221,7 @@ extension RedisClient {
value.convertedToRESPValue()
]
return send(command: "HSET", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
......@@ -246,7 +246,7 @@ extension RedisClient {
value.convertedToRESPValue()
]
return send(command: "HSETNX", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
......@@ -325,7 +325,7 @@ extension RedisClient {
args.append(convertingContentsOf: fields)
return send(command: "HMGET", with: args)
.map(to: [RESPValue].self)
.tryConverting(to: [RESPValue].self)
}
/// Gets the values of a hash for the fields specified as a specific type.
......@@ -382,7 +382,7 @@ extension RedisClient {
public func hgetall(from key: RedisKey) -> EventLoopFuture<[String: RESPValue]> {
let args = [RESPValue(from: key)]
return send(command: "HGETALL", with: args)
.map(to: [RESPValue].self)
.tryConverting(to: [RESPValue].self)
.flatMapThrowing(Self._mapHashResponse)
}
......@@ -453,6 +453,6 @@ extension RedisClient {
amount.convertedToRESPValue()
]
return send(command: command, with: args)
.map()
.tryConverting()
}
}
......@@ -25,7 +25,7 @@ extension RedisClient {
public func llen(of key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "LLEN", with: args)
.map()
.tryConverting()
}
/// Gets the element from a list stored at the provided index position.
......@@ -104,7 +104,7 @@ extension RedisClient {
value.convertedToRESPValue()
]
return send(command: "LREM", with: args)
.map()
.tryConverting()
}
}
......@@ -266,7 +266,7 @@ extension RedisClient {
.init(bulk: lastIndex)
]
return send(command: "LRANGE", with: args)
.map()
.tryConverting()
}
/// Gets all elements from a List within the the specified inclusive bounds of 0-based indices.
......@@ -668,7 +668,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "LINSERT", with: args)
.map()
.tryConverting()
}
}
......@@ -714,7 +714,7 @@ extension RedisClient {
args.append(convertingContentsOf: elements)
return send(command: "LPUSH", with: args)
.map()
.tryConverting()
}
/// Pushes all of the provided elements into a list.
......@@ -745,7 +745,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "LPUSHX", with: args)
.map()
.tryConverting()
}
}
......@@ -788,7 +788,7 @@ extension RedisClient {
args.append(convertingContentsOf: elements)
return send(command: "RPUSH", with: args)
.map()
.tryConverting()
}
/// Pushes all of the provided elements into a list.
......@@ -818,7 +818,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "RPUSHX", with: args)
.map()
.tryConverting()
}
}
......
......@@ -28,7 +28,7 @@ extension RedisClient {
public func smembers(of key: RedisKey) -> EventLoopFuture<[RESPValue]> {
let args = [RESPValue(from: key)]
return send(command: "SMEMBERS", with: args)
.map()
.tryConverting()
}
/// Gets all of the elements contained in a set.
......@@ -61,7 +61,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "SISMEMBER", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
......@@ -73,7 +73,7 @@ extension RedisClient {
public func scard(of key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "SCARD", with: args)
.map()
.tryConverting()
}
/// Adds elements to a set.
......@@ -91,7 +91,7 @@ extension RedisClient {
args.append(convertingContentsOf: elements)
return send(command: "SADD", with: args)
.map()
.tryConverting()
}
/// Adds elements to a set.
......@@ -121,7 +121,7 @@ extension RedisClient {
args.append(convertingContentsOf: elements)
return send(command: "SREM", with: args)
.map()
.tryConverting()
}
/// Removes elements from a set.
......@@ -153,7 +153,7 @@ extension RedisClient {
.init(bulk: count)
]
return send(command: "SPOP", with: args)
.map()
.tryConverting()
}
/// Randomly selects and removes one or more elements in a set.
......@@ -193,7 +193,7 @@ extension RedisClient {
.init(bulk: count)
]
return send(command: "SRANDMEMBER", with: args)
.map()
.tryConverting()
}
/// Randomly selects one or more elements in a set.
......@@ -236,7 +236,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "SMOVE", with: args)
.map()
.tryConverting()
.map { return $0 == 1 }
}
......@@ -297,7 +297,7 @@ extension RedisClient {
let args = keys.map(RESPValue.init)
return send(command: "SDIFF", with: args)
.map()
.tryConverting()
}
/// Calculates the difference between two or more sets.
......@@ -349,7 +349,7 @@ extension RedisClient {
args.append(convertingContentsOf: keys)
return send(command: "SDIFFSTORE", with: args)
.map()
.tryConverting()
}
}
......@@ -366,7 +366,7 @@ extension RedisClient {
let args = keys.map(RESPValue.init)
return send(command: "SINTER", with: args)
.map()
.tryConverting()
}
/// Calculates the intersection of two or more sets.
......@@ -418,7 +418,7 @@ extension RedisClient {
args.append(convertingContentsOf: keys)
return send(command: "SINTERSTORE", with: args)
.map()
.tryConverting()
}
}
......@@ -435,7 +435,7 @@ extension RedisClient {
let args = keys.map(RESPValue.init)
return send(command: "SUNION", with: args)
.map()
.tryConverting()
}
/// Calculates the union of two or more sets.
......@@ -487,6 +487,6 @@ extension RedisClient {
args.append(convertingContentsOf: keys)
return send(command: "SUNIONSTORE", with: args)
.map()
.tryConverting()
}
}
......@@ -123,7 +123,7 @@ extension RedisClient {
}
return self.send(command: "ZADD", with: args)
.map()
.tryConverting()
}
/// Adds elements to a sorted set, assigning their score to the values provided.
......@@ -177,7 +177,7 @@ extension RedisClient {
public func zcard(of key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "ZCARD", with: args)
.map()
.tryConverting()
}
/// Gets the score of the specified element in a stored set.
......@@ -268,7 +268,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "ZRANK", with: args)
.map()
.tryConverting()
}
/// Returns the rank (index) of the specified element in a sorted set.
......@@ -287,7 +287,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "ZREVRANK", with: args)
.map()
.tryConverting()
}
}
......@@ -369,7 +369,7 @@ extension RedisClient {
.init(bulk: range.max.description)
]
return self.send(command: "ZCOUNT", with: args)
.map()
.tryConverting()
}
/// Returns the count of elements in a SortedSet with a score within the inclusive range specified.
......@@ -498,7 +498,7 @@ extension RedisClient {
.init(bulk: range.max.description)
]
return self.send(command: "ZLEXCOUNT", with: args)
.map()
.tryConverting()
}
/// Returns the count of elements in a SortedSet whose lexiographical value is greater than a minimum value.
......@@ -611,7 +611,7 @@ extension RedisClient {
}
return send(command: command, with: args)
.map(to: [RESPValue].self)
.tryConverting(to: [RESPValue].self)
.flatMapThrowing { return try Self._mapSortedSetResponse($0, scoreIsFirst: true) }
}
}
......@@ -779,7 +779,7 @@ extension RedisClient {
element.convertedToRESPValue()
]
return send(command: "ZINCRBY", with: args)
.map()
.tryConverting()
}
}
......@@ -867,7 +867,7 @@ extension RedisClient {
}
return send(command: command, with: args)
.map()
.tryConverting()
}
}
......@@ -1266,7 +1266,7 @@ extension RedisClient {
if withScores { args.append(.init(bulk: "WITHSCORES")) }
return send(command: command, with: args)
.map()
.tryConverting()
}
}
......@@ -1544,7 +1544,7 @@ extension RedisClient {
}
return send(command: command, with: args)
.map()
.tryConverting()
}
}
......@@ -1736,7 +1736,7 @@ extension RedisClient {
}
return send(command: command, with: args)
.map()
.tryConverting()
}
}
......@@ -1758,7 +1758,7 @@ extension RedisClient {
args.append(convertingContentsOf: elements)
return send(command: "ZREM", with: args)
.map()
.tryConverting()
}
/// Removes the specified elements from a sorted set.
......@@ -1803,7 +1803,7 @@ extension RedisClient {
.init(bulk: range.max.description)
]
return send(command: "ZREMRANGEBYLEX", with: args)
.map()
.tryConverting()
}
/// Removes elements from a SortedSet whose lexiographical values are greater than a minimum value.
......@@ -1871,7 +1871,7 @@ extension RedisClient {
.init(bulk: lastIndex)
]
return self.send(command: "ZREMRANGEBYRANK", with: args)
.map()
.tryConverting()
}
/// Removes all elements from a SortedSet within the specified inclusive bounds of 0-based indices.
......@@ -1959,7 +1959,7 @@ extension RedisClient {
.init(bulk: range.max.description)
]
return self.send(command: "ZREMRANGEBYSCORE", with: args)
.map()
.tryConverting()
}
/// Removes elements from a SortedSet whose score is within the inclusive range specified.
......
......@@ -53,7 +53,7 @@ extension RedisClient {
let args = keys.map(RESPValue.init)
return send(command: "MGET", with: args)
.map()
.tryConverting()
}
/// Gets the values of all specified keys, using `.null` to represent non-existant values.
......@@ -209,7 +209,7 @@ extension RedisClient {
value.convertedToRESPValue()
]
return send(command: "APPEND", with: args)
.map()
.tryConverting()
}
/// Sets the value stored in the key provided, overwriting the previous value.
......@@ -289,7 +289,7 @@ extension RedisClient {
value.convertedToRESPValue()
]
return self.send(command: "SETNX", with: args)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { $0 == 1 }
}
......@@ -368,7 +368,7 @@ extension RedisClient {
@inlinable
public func msetnx<Value: RESPValueConvertible>(_ operations: [RedisKey: Value]) -> EventLoopFuture<Bool> {
return _mset(command: "MSETNX", operations)
.map(to: Int.self)
.tryConverting(to: Int.self)
.map { return $0 == 1 }
}
......@@ -402,7 +402,7 @@ extension RedisClient {
public func increment(_ key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "INCR", with: args)
.map()
.tryConverting()
}
/// Increments the stored value by the amount desired .
......@@ -422,7 +422,7 @@ extension RedisClient {
.init(bulk: count)
]
return send(command: "INCRBY", with: args)
.map()
.tryConverting()
}
/// Increments the stored value by the amount desired.
......@@ -442,7 +442,7 @@ extension RedisClient {
count.convertedToRESPValue()
]
return send(command: "INCRBYFLOAT", with: args)
.map()
.tryConverting()
}
}
......@@ -458,7 +458,7 @@ extension RedisClient {
public func decrement(_ key: RedisKey) -> EventLoopFuture<Int> {
let args = [RESPValue(from: key)]
return send(command: "DECR", with: args)
.map()
.tryConverting()
}
/// Decrements the stored valye by the amount desired.
......@@ -478,6 +478,6 @@ extension RedisClient {
.init(bulk: count)
]
return send(command: "DECRBY", with: args)
.map()
.tryConverting()
}
}
......@@ -171,20 +171,20 @@ extension RESPValue: RESPValueConvertible {
import NIO
extension EventLoopFuture where Value == RESPValue {
/// Attempts to convert the `RESPValue` to the desired `RESPValueConvertible` type.
/// If the `RESPValueConvertible.init(_:)` returns `nil`, then the `EventLoopFuture` will fail.
/// Attempts to convert the resolved RESPValue to the desired type.
///
/// This method is intended to be used much like a precondition in synchronous code, where a value is expected to be available from the `RESPValue`.
/// - Important: If the `RESPValueConvertible` initializer fails, then the `NIO.EventLoopFuture` will fail.
/// - Parameter to: The desired type to convert to.
/// - Returns: An `EventLoopFuture` that resolves a value of the desired type.
@inlinable
public func map<T>(
/// - Throws: `RedisClientError.failedRESPConversion(to:)`
/// - Returns: A `NIO.EventLoopFuture` that resolves a value of the desired type or fails if the conversion does.
@usableFromInline
internal func tryConverting<T: RESPValueConvertible>(
to type: T.Type = T.self,
file: StaticString = #function,
function: StaticString = #function,
file: StaticString = #file,
line: UInt = #line
) -> EventLoopFuture<T>
where T: RESPValueConvertible
{
return self.flatMapThrowing {
) -> EventLoopFuture<T> {
return self.flatMapThrowing(file: file, line: line) {