using System.Threading; using System; using System.Collections.Generic; using System.Threading.Tasks; using SpotifyAPI.Web.Http; using System.Runtime.CompilerServices; namespace SpotifyAPI.Web { public class SimplePaginator : IPaginator { protected virtual Task ShouldContinue(List results, IPaginatable page) { return Task.FromResult(true); } protected virtual Task ShouldContinue(List results, IPaginatable page) { return Task.FromResult(true); } public async Task> PaginateAll(IPaginatable firstPage, IAPIConnector connector) { Ensure.ArgumentNotNull(firstPage, nameof(firstPage)); Ensure.ArgumentNotNull(connector, nameof(connector)); var page = firstPage; var results = new List(); if (page.Items != null) { results.AddRange(page.Items); } while (page.Next != null && await ShouldContinue(results, page).ConfigureAwait(false)) { page = await connector.Get>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false); if (page.Items != null) { results.AddRange(page.Items); } } return results; } public async Task> PaginateAll( IPaginatable firstPage, Func> mapper, IAPIConnector connector ) { Ensure.ArgumentNotNull(firstPage, nameof(firstPage)); Ensure.ArgumentNotNull(mapper, nameof(mapper)); Ensure.ArgumentNotNull(connector, nameof(connector)); var page = firstPage; var results = new List(); if (page.Items != null) { results.AddRange(page.Items); } while (page.Next != null && await ShouldContinue(results, page).ConfigureAwait(false)) { var next = await connector.Get(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false); page = mapper(next); if (page.Items != null) { results.AddRange(page.Items); } } return results; } public async IAsyncEnumerable Paginate( IPaginatable firstPage, IAPIConnector connector, [EnumeratorCancellation] CancellationToken cancel = default) { Ensure.ArgumentNotNull(firstPage, nameof(firstPage)); Ensure.ArgumentNotNull(connector, nameof(connector)); if (firstPage.Items == null) { throw new ArgumentException("The first page has to contain an Items list!", nameof(firstPage)); } var page = firstPage; foreach (var item in page.Items) { yield return item; } while (page.Next != null) { page = await connector.Get>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false); foreach (var item in page.Items!) { yield return item; } } } public async IAsyncEnumerable Paginate( IPaginatable firstPage, Func> mapper, IAPIConnector connector, [EnumeratorCancellation] CancellationToken cancel = default) { Ensure.ArgumentNotNull(firstPage, nameof(firstPage)); Ensure.ArgumentNotNull(mapper, nameof(mapper)); Ensure.ArgumentNotNull(connector, nameof(connector)); if (firstPage.Items == null) { throw new ArgumentException("The first page has to contain an Items list!", nameof(firstPage)); } var page = firstPage; foreach (var item in page.Items) { yield return item; } while (page.Next != null) { var next = await connector.Get(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false); page = mapper(next); foreach (var item in page.Items!) { yield return item; } } } } }