Skip to content

Commit 6bd5df7

Browse files
committed
Add map overloads for casting RESPValue elements in a Collection
1 parent 17fa5da commit 6bd5df7

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

Sources/RediStack/RESP/RESPValue.swift

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,67 @@ extension RangeReplaceableCollection where Element == RESPValue {
254254
elementsToCopy.forEach { closure(&self, $0) }
255255
}
256256
}
257+
258+
// MARK: Mapping RESPValue Collections
259+
260+
extension Collection where Element == RESPValue {
261+
/// Maps the elements of the sequence to the type desired.
262+
/// - Parameter t1: The type to convert the elements to.
263+
/// - Returns: An array of the results from the conversions.
264+
@inlinable
265+
public func map<T: RESPValueConvertible>(as t1: T.Type) -> [T?] {
266+
return self.map(T.init(fromRESP:))
267+
}
268+
269+
/// Maps the first element to the type sepcified, with all remaining elements mapped to the second type.
270+
@inlinable
271+
public func map<T1, T2>(firstAs t1: T1.Type, remainingAs t2: T2.Type) -> (T1?, [T2?])
272+
where T1: RESPValueConvertible, T2: RESPValueConvertible
273+
{
274+
guard self.count > 1 else { return (nil, []) }
275+
let first = self.first.map(T1.init(fromRESP:)) ?? nil
276+
let remaining = self.dropFirst().map(T2.init(fromRESP:))
277+
return (first, remaining)
278+
}
279+
280+
/// Maps the first and second elements to the types specified, with any remaining mapped to the third type.
281+
@inlinable
282+
public func map<T1, T2, T3>(
283+
firstAs t1: T1.Type,
284+
_ t2: T2.Type,
285+
remainingAs t3: T3.Type
286+
) -> (T1?, T2?, [T3?])
287+
where T1: RESPValueConvertible, T2: RESPValueConvertible, T3: RESPValueConvertible
288+
{
289+
guard self.count > 2 else { return (nil, nil, []) }
290+
let first = self.first.map(T1.init(fromRESP:)) ?? nil
291+
let second = T2.init(fromRESP: self[self.index(after: self.startIndex)])
292+
let remaining = self.dropFirst(2).map(T3.init(fromRESP:))
293+
return (first, second, remaining)
294+
}
295+
296+
/// Maps the first, second, and third elements to the types specified, with any remaining mapped to the fourth type.
297+
@inlinable
298+
public func map<T1, T2, T3, T4>(
299+
firstAs t1: T1.Type,
300+
_ t2: T2.Type,
301+
_ t3: T3.Type,
302+
remainingAs t4: T4.Type
303+
) -> (T1?, T2?, T3?, [T4?])
304+
where T1: RESPValueConvertible, T2: RESPValueConvertible, T3: RESPValueConvertible, T4: RESPValueConvertible
305+
{
306+
guard self.count > 3 else { return (nil, nil, nil, []) }
307+
308+
let firstIndex = self.startIndex
309+
let secondIndex = self.index(after: firstIndex)
310+
let thirdIndex = self.index(after: secondIndex)
311+
312+
let first = T1.init(fromRESP: self[firstIndex])
313+
let second = T2.init(fromRESP: self[secondIndex])
314+
let third = T3.init(fromRESP: self[thirdIndex])
315+
let remaining = self.dropFirst(3).map(T4.init(fromRESP:))
316+
317+
return (first, second, third, remaining)
318+
}
319+
}
320+

0 commit comments

Comments
 (0)