Further refined IPaginator, making it possible to do search pagination!

This commit is contained in:
Jonas Dellinger 2020-05-05 17:52:23 +02:00
parent 997d29cfc5
commit cd650a7e6d
7 changed files with 68 additions and 9 deletions

View File

@ -9,5 +9,8 @@ namespace SpotifyAPI.Web
{ {
Task<List<T>> Paginate<T>(Paging<T> firstPage, IAPIConnector connector); Task<List<T>> Paginate<T>(Paging<T> firstPage, IAPIConnector connector);
Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IAPIConnector connector); Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IAPIConnector connector);
Task<List<T>> Paginate<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper, IAPIConnector connector);
Task<List<T>> Paginate<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper, IAPIConnector connector);
} }
} }

View File

@ -23,7 +23,9 @@ namespace SpotifyAPI.Web
ITracksClient Tracks { get; } ITracksClient Tracks { get; }
Task<List<T>> Paginate<T>(Paging<T> firstPage); Task<List<T>> Paginate<T>(Paging<T> firstPage);
Task<List<T>> Paginate<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper);
Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage); Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage);
Task<List<T>> Paginate<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper);
Task<List<T>> Paginate<T>(Paging<T> firstPage, IPaginator paginator); Task<List<T>> Paginate<T>(Paging<T> firstPage, IPaginator paginator);
Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator); Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator);
} }

View File

@ -7,9 +7,13 @@ namespace SpotifyAPI.Web
{ {
public class SimplePaginator : IPaginator public class SimplePaginator : IPaginator
{ {
protected virtual bool ShouldContinue<T>(List<T> results, Paging<T> page) protected virtual Task<bool> ShouldContinue<T>(List<T> results, Paging<T> page)
{ {
return true; return Task.FromResult(true);
}
protected virtual Task<bool> ShouldContinue<T, TNext>(List<T> results, Paging<T, TNext> page)
{
return Task.FromResult(true);
} }
public async Task<List<T>> Paginate<T>(Paging<T> firstPage, IAPIConnector connector) public async Task<List<T>> Paginate<T>(Paging<T> firstPage, IAPIConnector connector)
@ -20,7 +24,7 @@ namespace SpotifyAPI.Web
var page = firstPage; var page = firstPage;
var results = new List<T>(); var results = new List<T>();
results.AddRange(firstPage.Items); results.AddRange(firstPage.Items);
while (page.Next != null && ShouldContinue(results, page)) while (page.Next != null && await ShouldContinue(results, page).ConfigureAwait(false))
{ {
page = await connector.Get<Paging<T>>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false); page = await connector.Get<Paging<T>>(new Uri(page.Next, UriKind.Absolute)).ConfigureAwait(false);
results.AddRange(page.Items); results.AddRange(page.Items);
@ -36,5 +40,34 @@ namespace SpotifyAPI.Web
var firstPage = await getFirstPage().ConfigureAwait(false); var firstPage = await getFirstPage().ConfigureAwait(false);
return await Paginate(firstPage, connector).ConfigureAwait(false); return await Paginate(firstPage, connector).ConfigureAwait(false);
} }
public async Task<List<T>> Paginate<T, TNext>(
Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> 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<T>();
results.AddRange(firstPage.Items);
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);
results.AddRange(page.Items);
}
return results;
}
public async Task<List<T>> Paginate<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper, IAPIConnector connector)
{
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
var firstPage = await getFirstPage().ConfigureAwait(false);
return await Paginate(firstPage, mapper, connector).ConfigureAwait(false);
}
} }
} }

View File

@ -49,6 +49,11 @@ namespace SpotifyAPI.Web
return DefaultPaginator.Paginate(firstPage, _apiConnector); return DefaultPaginator.Paginate(firstPage, _apiConnector);
} }
public Task<List<T>> Paginate<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper)
{
return DefaultPaginator.Paginate(firstPage, mapper, _apiConnector);
}
public Task<List<T>> Paginate<T>(Paging<T> firstPage, IPaginator paginator) public Task<List<T>> Paginate<T>(Paging<T> firstPage, IPaginator paginator)
{ {
Ensure.ArgumentNotNull(paginator, nameof(paginator)); Ensure.ArgumentNotNull(paginator, nameof(paginator));
@ -61,6 +66,11 @@ namespace SpotifyAPI.Web
return DefaultPaginator.Paginate(getFirstPage, _apiConnector); return DefaultPaginator.Paginate(getFirstPage, _apiConnector);
} }
public Task<List<T>> Paginate<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper)
{
return DefaultPaginator.Paginate(getFirstPage, mapper, _apiConnector);
}
public Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator) public Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator)
{ {
Ensure.ArgumentNotNull(paginator, nameof(paginator)); Ensure.ArgumentNotNull(paginator, nameof(paginator));

View File

@ -158,7 +158,7 @@ namespace SpotifyAPI.Web.Http
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
Ensure.ArgumentNotNull(method, nameof(method)); Ensure.ArgumentNotNull(method, nameof(method));
return new Request(parameters) return new Request(new Dictionary<string, string>(), parameters)
{ {
BaseAddress = _baseAddress, BaseAddress = _baseAddress,
Endpoint = uri, Endpoint = uri,

View File

@ -12,4 +12,15 @@ namespace SpotifyAPI.Web
public string Previous { get; private set; } public string Previous { get; private set; }
public int Total { get; private set; } public int Total { get; private set; }
} }
public class Paging<T, TNext>
{
public string Href { get; private set; }
public List<T> Items { get; private set; }
public int Limit { get; private set; }
public string Next { get; private set; }
public int Offset { get; private set; }
public string Previous { get; private set; }
public int Total { get; private set; }
}
} }

View File

@ -2,10 +2,10 @@ namespace SpotifyAPI.Web
{ {
public class SearchResponse public class SearchResponse
{ {
public Paging<FullArtist> Artists { get; private set; } public Paging<FullArtist, SearchResponse> Artists { get; private set; }
public Paging<SimpleAlbum> Albums { get; private set; } public Paging<SimpleAlbum, SearchResponse> Albums { get; private set; }
public Paging<FullTrack> Tracks { get; private set; } public Paging<FullTrack, SearchResponse> Tracks { get; private set; }
public Paging<SimpleShow> Shows { get; private set; } public Paging<SimpleShow, SearchResponse> Shows { get; private set; }
public Paging<SimpleEpisode> Episodes { get; private set; } public Paging<SimpleEpisode, SearchResponse> Episodes { get; private set; }
} }
} }