2020-05-20 19:59:11 +01:00
|
|
|
using System.Threading;
|
2020-05-05 04:26:37 +01:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using SpotifyAPI.Web.Http;
|
2020-05-20 19:59:11 +01:00
|
|
|
using System.Runtime.CompilerServices;
|
2020-05-05 04:26:37 +01:00
|
|
|
|
|
|
|
namespace SpotifyAPI.Web
|
|
|
|
{
|
|
|
|
public class SimplePaginator : IPaginator
|
|
|
|
{
|
2020-06-13 11:55:48 +01:00
|
|
|
protected virtual Task<bool> ShouldContinue<T>(List<T> results, IPaginatable<T> page)
|
2020-05-05 04:26:37 +01:00
|
|
|
{
|
2020-05-05 16:52:23 +01:00
|
|
|
return Task.FromResult(true);
|
|
|
|
}
|
2020-06-13 11:55:48 +01:00
|
|
|
protected virtual Task<bool> ShouldContinue<T, TNext>(List<T> results, IPaginatable<T, TNext> page)
|
2020-05-05 16:52:23 +01:00
|
|
|
{
|
|
|
|
return Task.FromResult(true);
|
2020-05-05 04:26:37 +01:00
|
|
|
}
|
|
|
|
|
2020-06-13 11:55:48 +01:00
|
|
|
public async Task<IList<T>> PaginateAll<T>(IPaginatable<T> firstPage, IAPIConnector connector)
|
2020-05-05 04:26:37 +01:00
|
|
|
{
|
2020-05-05 04:45:33 +01:00
|
|
|
Ensure.ArgumentNotNull(firstPage, nameof(firstPage));
|
|
|
|
Ensure.ArgumentNotNull(connector, nameof(connector));
|
|
|
|
|
2020-05-05 04:26:37 +01:00
|
|
|
var page = firstPage;
|
|
|
|
var results = new List<T>();
|
2020-11-13 13:43:00 +00:00
|
|
|
if (page.Items != null)
|
|
|
|
{
|
|
|
|
results.AddRange(page.Items);
|
|
|
|
}
|
2020-05-05 16:52:23 +01:00
|
|
|
while (page.Next != null && await ShouldContinue(results, page).ConfigureAwait(false))
|
2020-05-05 04:26:37 +01:00
|
|
|
{
|
|
|
|
page = await connector.Get<Paging<T>>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false);
|
2020-11-13 13:43:00 +00:00
|
|
|
if (page.Items != null)
|
|
|
|
{
|
|
|
|
results.AddRange(page.Items);
|
|
|
|
}
|
2020-05-05 04:26:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2020-05-30 22:20:42 +01:00
|
|
|
public async Task<IList<T>> PaginateAll<T, TNext>(
|
2020-06-13 11:55:48 +01:00
|
|
|
IPaginatable<T, TNext> firstPage, Func<TNext, IPaginatable<T, TNext>> mapper, IAPIConnector connector
|
2020-05-05 16:52:23 +01:00
|
|
|
)
|
|
|
|
{
|
|
|
|
Ensure.ArgumentNotNull(firstPage, nameof(firstPage));
|
|
|
|
Ensure.ArgumentNotNull(mapper, nameof(mapper));
|
|
|
|
Ensure.ArgumentNotNull(connector, nameof(connector));
|
|
|
|
|
|
|
|
var page = firstPage;
|
|
|
|
var results = new List<T>();
|
2020-11-13 13:43:00 +00:00
|
|
|
if (page.Items != null)
|
|
|
|
{
|
|
|
|
results.AddRange(page.Items);
|
|
|
|
}
|
2020-05-05 16:52:23 +01:00
|
|
|
while (page.Next != null && await ShouldContinue(results, page).ConfigureAwait(false))
|
|
|
|
{
|
|
|
|
var next = await connector.Get<TNext>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false);
|
|
|
|
page = mapper(next);
|
2020-11-13 13:43:00 +00:00
|
|
|
if (page.Items != null)
|
|
|
|
{
|
|
|
|
results.AddRange(page.Items);
|
|
|
|
}
|
2020-05-05 16:52:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2021-03-02 11:19:55 +00:00
|
|
|
#if !NETSTANDARD2_0
|
2020-05-20 19:59:11 +01:00
|
|
|
public async IAsyncEnumerable<T> Paginate<T>(
|
2020-06-13 11:55:48 +01:00
|
|
|
IPaginatable<T> firstPage,
|
2020-05-20 19:59:11 +01:00
|
|
|
IAPIConnector connector,
|
|
|
|
[EnumeratorCancellation] CancellationToken cancel = default)
|
|
|
|
{
|
|
|
|
Ensure.ArgumentNotNull(firstPage, nameof(firstPage));
|
|
|
|
Ensure.ArgumentNotNull(connector, nameof(connector));
|
2020-07-13 15:03:19 +01:00
|
|
|
if (firstPage.Items == null)
|
|
|
|
{
|
|
|
|
throw new ArgumentException("The first page has to contain an Items list!", nameof(firstPage));
|
|
|
|
}
|
2020-05-20 19:59:11 +01:00
|
|
|
|
|
|
|
var page = firstPage;
|
|
|
|
foreach (var item in page.Items)
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
while (page.Next != null)
|
|
|
|
{
|
|
|
|
page = await connector.Get<Paging<T>>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false);
|
2020-07-13 15:03:19 +01:00
|
|
|
foreach (var item in page.Items!)
|
2020-05-20 19:59:11 +01:00
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<T> Paginate<T, TNext>(
|
2020-06-13 11:55:48 +01:00
|
|
|
IPaginatable<T, TNext> firstPage,
|
|
|
|
Func<TNext, IPaginatable<T, TNext>> mapper,
|
2020-05-20 19:59:11 +01:00
|
|
|
IAPIConnector connector,
|
|
|
|
[EnumeratorCancellation] CancellationToken cancel = default)
|
2020-05-05 16:52:23 +01:00
|
|
|
{
|
2020-05-20 19:59:11 +01:00
|
|
|
Ensure.ArgumentNotNull(firstPage, nameof(firstPage));
|
|
|
|
Ensure.ArgumentNotNull(mapper, nameof(mapper));
|
|
|
|
Ensure.ArgumentNotNull(connector, nameof(connector));
|
2020-07-13 15:03:19 +01:00
|
|
|
if (firstPage.Items == null)
|
|
|
|
{
|
|
|
|
throw new ArgumentException("The first page has to contain an Items list!", nameof(firstPage));
|
|
|
|
}
|
2020-05-05 16:52:23 +01:00
|
|
|
|
2020-05-20 19:59:11 +01:00
|
|
|
var page = firstPage;
|
|
|
|
foreach (var item in page.Items)
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
while (page.Next != null)
|
|
|
|
{
|
|
|
|
var next = await connector.Get<TNext>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false);
|
|
|
|
page = mapper(next);
|
2020-07-13 15:03:19 +01:00
|
|
|
foreach (var item in page.Items!)
|
2020-05-20 19:59:11 +01:00
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
}
|
2020-05-05 16:52:23 +01:00
|
|
|
}
|
2020-05-20 19:59:11 +01:00
|
|
|
#endif
|
2020-05-05 04:26:37 +01:00
|
|
|
}
|
|
|
|
}
|