Skip to content

Commit 6e45f56

Browse files
committed
Merge branch 'range-api' into 'master'
Rework SortedSet and List range APIs See merge request Mordil/swift-redi-stack!98
2 parents 346d37d + 2499998 commit 6e45f56

File tree

5 files changed

+1712
-184
lines changed

5 files changed

+1712
-184
lines changed

Sources/RediStack/Commands/ListCommands.swift

Lines changed: 284 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,19 @@ extension RedisClient {
9090
return send(command: "LREM", with: args)
9191
.convertFromRESPValue()
9292
}
93+
}
94+
95+
// MARK: LTrim
9396

94-
/// Trims a list to only contain elements within the specified inclusive bounds of 0-based indices.
97+
extension RedisClient {
98+
/// Trims a List to only contain elements within the specified inclusive bounds of 0-based indices.
9599
///
96100
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
97101
/// - Parameters:
98-
/// - key: The key of the list to trim.
102+
/// - key: The key of the List to trim.
99103
/// - start: The index of the first element to keep.
100104
/// - stop: The index of the last element to keep.
101-
/// - Returns: An `EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
105+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
102106
@inlinable
103107
public func ltrim(_ key: RedisKey, before start: Int, after stop: Int) -> EventLoopFuture<Void> {
104108
let args: [RESPValue] = [
@@ -109,28 +113,295 @@ extension RedisClient {
109113
return send(command: "LTRIM", with: args)
110114
.map { _ in () }
111115
}
116+
117+
/// Trims a List to only contain elements within the specified inclusive bounds of 0-based indices.
118+
///
119+
/// To keep elements 4 through 7:
120+
/// ```swift
121+
/// client.ltrim("myList", keepingIndices: 3...6)
122+
/// ```
123+
///
124+
/// To keep the last 4 through 7 elements:
125+
/// ```swift
126+
/// client.ltrim("myList", keepingIndices: (-7)...(-4))
127+
/// ```
128+
///
129+
/// To keep the first and last 4 elements:
130+
/// ```swift
131+
/// client.ltrim("myList", keepingIndices: (-4)...3)
132+
/// ```
133+
///
134+
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
135+
/// - Warning: A `ClosedRange` cannot be created where `upperBound` is less than `lowerBound`; so while Redis may support `0...-1`,
136+
/// `ClosedRange` will trigger a precondition failure.
137+
///
138+
/// If you need such a range, use `ltrim(_:before:after:)` instead.
139+
/// - Parameters:
140+
/// - key: The key of the List to trim.
141+
/// - range: The range of indices that should be kept in the List.
142+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
143+
@inlinable
144+
public func ltrim(_ key: RedisKey, keepingIndices range: ClosedRange<Int>) -> EventLoopFuture<Void> {
145+
return self.ltrim(key, before: range.lowerBound, after: range.upperBound)
146+
}
147+
148+
/// Trims a List to only contain elements starting from the specified index.
149+
///
150+
/// To keep all but the first 3 elements:
151+
/// ```swift
152+
/// client.ltrim("myList", keepingIndices: 3...)
153+
/// ```
154+
///
155+
/// To keep the last 4 elements:
156+
/// ```swift
157+
/// client.ltrim("myList", keepingIndices: (-4)...)
158+
/// ```
159+
///
160+
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
161+
/// - Parameters:
162+
/// - key: The key of the List to trim.
163+
/// - range: The range of indices that should be kept in the List.
164+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
165+
@inlinable
166+
public func ltrim(_ key: RedisKey, keepingIndices range: PartialRangeFrom<Int>) -> EventLoopFuture<Void> {
167+
return self.ltrim(key, before: range.lowerBound, after: -1)
168+
}
169+
170+
/// Trims a List to only contain elements before the specified index.
171+
///
172+
/// To keep the first 3 elements:
173+
/// ```swift
174+
/// client.ltrim("myList", keepingIndices: ..<3)
175+
/// ```
176+
///
177+
/// To keep all but the last 4 elements:
178+
/// ```swift
179+
/// client.ltrim("myList", keepingIndices: ..<(-4))
180+
/// ```
181+
///
182+
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
183+
/// - Parameters:
184+
/// - key: The key of the List to trim.
185+
/// - range: The range of indices that should be kept in the List.
186+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
187+
@inlinable
188+
public func ltrim(_ key: RedisKey, keepingIndices range: PartialRangeUpTo<Int>) -> EventLoopFuture<Void> {
189+
return self.ltrim(key, before: 0, after: range.upperBound - 1)
190+
}
191+
192+
/// Trims a List to only contain elements up to the specified index.
193+
///
194+
/// To keep the first 4 elements:
195+
/// ```swift
196+
/// client.ltrim("myList", keepingIndices: ...3)
197+
/// ```
198+
///
199+
/// To keep all but the last 3 elements:
200+
/// ```swift
201+
/// client.ltrim("myList", keepingIndices: ...(-4))
202+
/// ```
203+
///
204+
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
205+
/// - Parameters:
206+
/// - key: The key of the List to trim.
207+
/// - range: The range of indices that should be kept in the List.
208+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
209+
@inlinable
210+
public func ltrim(_ key: RedisKey, keepingIndices range: PartialRangeThrough<Int>) -> EventLoopFuture<Void> {
211+
return self.ltrim(key, before: 0, after: range.upperBound)
212+
}
213+
214+
/// Trims a List to only contain the elements from the specified index up to the index provided.
215+
///
216+
/// To keep the first 4 elements:
217+
/// ```swift
218+
/// client.ltrim("myList", keepingIndices: 0..<4)
219+
/// ```
220+
///
221+
/// To keep all but the last 3 elements:
222+
/// ```swift
223+
/// client.ltrim("myList", keepingIndices: 0..<(-3))
224+
/// ```
225+
///
226+
/// See [https://redis.io/commands/ltrim](https://redis.io/commands/ltrim)
227+
/// - Warning: A `Range` cannot be created where `upperBound` is less than `lowerBound`; so while Redis may support `0..<(-1)`,
228+
/// `Range` will trigger a precondition failure.
229+
///
230+
/// If you need such a range, use `ltrim(_:before:after:)` instead.
231+
/// - Parameters:
232+
/// - key: The key of the List to trim.
233+
/// - range: The range of indices that should be kept in the List.
234+
/// - Returns: A `NIO.EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
235+
@inlinable
236+
public func ltrim(_ key: RedisKey, keepingIndices range: Range<Int>) -> EventLoopFuture<Void> {
237+
return self.ltrim(key, before: range.lowerBound, after: range.upperBound - 1)
238+
}
239+
}
240+
241+
// MARK: LRange
112242

113-
/// Gets all elements from a list within the the specified inclusive bounds of 0-based indices.
243+
extension RedisClient {
244+
/// Gets all elements from a List within the the specified inclusive bounds of 0-based indices.
114245
///
115246
/// See [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
116247
/// - Parameters:
117-
/// - range: The range of inclusive indices of elements to get.
118-
/// - key: The key of the list.
119-
/// - Returns: A list of elements found within the range specified.
248+
/// - key: The key of the List.
249+
/// - firstIndex: The index of the first element to include in the range of elements returned.
250+
/// - lastIndex: The index of the last element to include in the range of elements returned.
251+
/// - Returns: An array of elements found within the range specified.
120252
@inlinable
121-
public func lrange(
122-
within range: (startIndex: Int, endIndex: Int),
123-
from key: RedisKey
124-
) -> EventLoopFuture<[RESPValue]> {
253+
public func lrange(from key: RedisKey, firstIndex: Int, lastIndex: Int) -> EventLoopFuture<[RESPValue]> {
125254
let args: [RESPValue] = [
126255
.init(bulk: key),
127-
.init(bulk: range.startIndex),
128-
.init(bulk: range.endIndex)
256+
.init(bulk: firstIndex),
257+
.init(bulk: lastIndex)
129258
]
130259
return send(command: "LRANGE", with: args)
131260
.convertFromRESPValue()
132261
}
262+
263+
/// Gets all elements from a List within the specified inclusive bounds of 0-based indices.
264+
///
265+
/// To get the elements at index 4 through 7:
266+
/// ```swift
267+
/// client.lrange(from: "myList", indices: 4...7)
268+
/// ```
269+
///
270+
/// To get the last 4 elements:
271+
/// ```swift
272+
/// client.lrange(from: "myList", indices: (-4)...(-1))
273+
/// ```
274+
///
275+
/// To get the first and last 4 elements:
276+
/// ```swift
277+
/// client.lrange(from: "myList", indices: (-4)...3)
278+
/// ```
279+
///
280+
/// To get the first element, and the last 4:
281+
/// ```swift
282+
/// client.lrange(from: "myList", indices: (-4)...0))
283+
/// ```
284+
///
285+
/// See [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
286+
/// - Warning: A `ClosedRange` cannot be created where `upperBound` is less than `lowerBound`; so while Redis may support `0...-1`,
287+
/// `ClosedRange` will trigger a precondition failure.
288+
///
289+
/// If you need such a range, use `lrange(from:firstIndex:lastIndex:)` instead.
290+
/// - Parameters:
291+
/// - key: The key of the List to return elements from.
292+
/// - range: The range of inclusive indices of elements to get.
293+
/// - Returns: An array of elements found within the range specified.
294+
@inlinable
295+
public func lrange(from key: RedisKey, indices range: ClosedRange<Int>) -> EventLoopFuture<[RESPValue]> {
296+
return self.lrange(from: key, firstIndex: range.lowerBound, lastIndex: range.upperBound)
297+
}
298+
299+
/// Gets all the elements from a List starting with the first index bound up to, but not including, the element at the last index bound.
300+
///
301+
/// To get the elements at index 4 through 7:
302+
/// ```swift
303+
/// client.lrange(from: "myList", indices: 4..<8)
304+
/// ```
305+
///
306+
/// To get the last 4 elements:
307+
/// ```swift
308+
/// client.lrange(from: "myList", indices: (-4)..<0)
309+
/// ```
310+
///
311+
/// To get the first and last 4 elements:
312+
/// ```swift
313+
/// client.lrange(from: "myList", indices: (-4)..<4)
314+
/// ```
315+
///
316+
/// To get the first element, and the last 4:
317+
/// ```swift
318+
/// client.lrange(from: "myList", indices: (-4)..<1)
319+
/// ```
320+
///
321+
/// See [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
322+
/// - Warning: A `Range` cannot be created where `upperBound` is less than `lowerBound`; so while Redis may support `0..<(-1)`,
323+
/// `Range` will trigger a precondition failure.
324+
///
325+
/// If you need such a range, use `lrange(from:firstIndex:lastIndex:)` instead.
326+
/// - Parameters:
327+
/// - key: The key of the List to return elements from.
328+
/// - range: The range of indices (inclusive lower, exclusive upper) elements to get.
329+
/// - Returns: An array of elements found within the range specified.
330+
@inlinable
331+
public func lrange(from key: RedisKey, indices range: Range<Int>) -> EventLoopFuture<[RESPValue]> {
332+
return self.lrange(from: key, firstIndex: range.lowerBound, lastIndex: range.upperBound - 1)
333+
}
133334

335+
/// Gets all elements from the index specified to the end of a List.
336+
///
337+
/// To get all except the first 2 elements of a List:
338+
/// ```swift
339+
/// client.lrange(from: "myList", fromIndex: 2)
340+
/// ```
341+
///
342+
/// To get the last 4 elements of a List:
343+
/// ```swift
344+
/// client.lrange(from: "myList", fromIndex: -4)
345+
/// ```
346+
///
347+
/// See `lrange(from:indices:)`, `lrange(from:firstIndex:lastIndex:)`, and [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
348+
/// - Parameters:
349+
/// - key: The key of the List to return elements from.
350+
/// - index: The index of the first element that will be in the returned values.
351+
/// - Returns: An array of elements from the List between the index and the end.
352+
@inlinable
353+
public func lrange(from key: RedisKey, fromIndex index: Int) -> EventLoopFuture<[RESPValue]> {
354+
return self.lrange(from: key, firstIndex: index, lastIndex: -1)
355+
}
356+
357+
/// Gets all elements from the the start of a List up to, and including, the element at the index specified.
358+
///
359+
/// To get the first 3 elements of a List:
360+
/// ```swift
361+
/// client.lrange(from: "myList", throughIndex: 2)
362+
/// ```
363+
///
364+
/// To get all except the last 3 elements of a List:
365+
/// ```swift
366+
/// client.lrange(from: "myList", throughIndex: -4)
367+
/// ```
368+
///
369+
/// See `lrange(from:indices:)`, `lrange(from:firstIndex:lastIndex:)`, and [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
370+
/// - Parameters:
371+
/// - key: The key of the List to return elements from.
372+
/// - index: The index of the last element that will be in the returned values.
373+
/// - Returns: An array of elements from the start of a List to the index.
374+
@inlinable
375+
public func lrange(from key: RedisKey, throughIndex index: Int) -> EventLoopFuture<[RESPValue]> {
376+
return self.lrange(from: key, firstIndex: 0, lastIndex: index)
377+
}
378+
379+
/// Gets all elements from the the start of a List up to, but not including, the element at the index specified.
380+
///
381+
/// To get the first 3 elements of a List:
382+
/// ```swift
383+
/// client.lrange(from: "myList", upToIndex: 3)
384+
/// ```
385+
///
386+
/// To get all except the last 3 elements of a List:
387+
/// ```swift
388+
/// client.lrange(from: "myList", upToIndex: -3)
389+
/// ```
390+
///
391+
/// See `lrange(from:indices:)`, `lrange(from:firstIndex:lastIndex:)`, and [https://redis.io/commands/lrange](https://redis.io/commands/lrange)
392+
/// - Parameters:
393+
/// - key: The key of the List to return elements from.
394+
/// - index: The index of the element to not include in the returned values.
395+
/// - Returns: An array of elements from the start of the List and up to the index.
396+
@inlinable
397+
public func lrange(from key: RedisKey, upToIndex index: Int) -> EventLoopFuture<[RESPValue]> {
398+
return self.lrange(from: key, firstIndex: 0, lastIndex: index - 1)
399+
}
400+
}
401+
402+
// MARK: Pop & Push
403+
404+
extension RedisClient {
134405
/// Pops the last element from a source list and pushes it to a destination list.
135406
///
136407
/// See [https://redis.io/commands/rpoplpush](https://redis.io/commands/rpoplpush)

0 commit comments

Comments
 (0)