-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathPagedEnumerator`1.cs
103 lines (87 loc) · 3.2 KB
/
PagedEnumerator`1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Disqord.Rest.Pagination;
using Qommon;
namespace Disqord.Rest;
/// <inheritdoc cref="IPagedEnumerator{TEntity}"/>
public abstract class PagedEnumerator<TEntity> : IPagedEnumerator<TEntity>
{
/// <inheritdoc/>
public abstract int PageSize { get; }
/// <summary>
/// Gets the current page of entities.
/// </summary>
public IReadOnlyList<TEntity> Current { get; private set; } = null!;
/// <inheritdoc/>
public IRestClient Client { get; }
/// <inheritdoc/>
public int RemainingCount { get; protected set; }
/// <inheritdoc/>
public IRestRequestOptions? Options { get; }
/// <inheritdoc/>
public CancellationToken CancellationToken { get; }
protected PagedEnumerator(IRestClient client, int remaining, IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
Guard.IsNotNull(client);
Guard.IsGreaterThanOrEqualTo(remaining, 0);
Client = client;
RemainingCount = remaining;
Options = options;
CancellationToken = cancellationToken;
}
/// <summary>
/// Gets the amount of entities in the next request page.
/// </summary>
protected int NextPageSize
{
get
{
var pageSize = PageSize;
var remaining = RemainingCount;
return remaining > pageSize
? pageSize
: remaining;
}
}
/// <summary>
/// Overridable logic that handles requesting the next page of entities.
/// </summary>
/// <param name="previousPage"> The previous value of <see cref="Current"/>. </param>
/// <param name="options"> The request options for the page request. </param>
/// <param name="cancellationToken"> The cancellation token to observe. </param>
protected abstract Task<IReadOnlyList<TEntity>> NextPageAsync(IReadOnlyList<TEntity>? previousPage,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default);
/// <inheritdoc/>
public async ValueTask<bool> MoveNextAsync(IRestRequestOptions? options = null)
{
if (RemainingCount == 0 || CancellationToken.IsCancellationRequested)
{
Current = default!;
return false;
}
var current = await NextPageAsync(Current, options ?? Options, CancellationToken).ConfigureAwait(false);
Current = current;
if (current.Count == 0)
{
RemainingCount = 0;
Current = default!;
return false;
}
// TODO: Rework paged enumerator
// if (current.Count < PageSize)
// {
// // If Discord returns less entities than the page size,
// // it means there are no more entities beyond the ones we just received.
// RemainingCount = 0;
// }
// else
// {
RemainingCount -= current.Count;
// }
return true;
}
/// <inheritdoc/>
public virtual ValueTask DisposeAsync()
=> default;
}