11using System . Runtime . CompilerServices ;
22using Jameak . CursorPagination . Abstractions ;
3+ using Jameak . CursorPagination . Abstractions . Enums ;
34using Jameak . CursorPagination . Enums ;
45using Jameak . CursorPagination . Page ;
56
67namespace Jameak . CursorPagination ;
78internal static class InternalPaginatorHelper
89{
10+ internal sealed record EmptyNextPageState (
11+ int ? TotalCount ,
12+ Func < bool > HasPreviousPageFunc ) ;
13+
14+ internal sealed record EmptyNextPageStateAsync (
15+ int ? TotalCount ,
16+ Func < Task < bool > > HasPreviousPageAsyncFunc ) ;
17+
918 internal static NextPage < TData , TCursor > DetermineNextPageFunc < TData , TCursor , TDataEntry > (
1019 Func < TCursor , NextPage < TData , TCursor > > nextPageFuncGenerator ,
1120 Func < TDataEntry , TCursor > createCursor ,
1221 TDataEntry ? nextCursorElement ,
13- int ? totalCount ,
22+ EmptyNextPageState emptyNextPageState ,
1423 bool ? hasNextPage ,
1524 ComputeNextPage computeNextPage ) where TCursor : ICursor
1625 {
1726 if ( nextCursorElement == null
1827 || CanSkipNextPageCheck ( computeNextPage , hasNextPage ) )
1928 {
20- return EmptyNextPage < TData , TCursor > ( totalCount ) ;
29+ return EmptyNextPage < TData , TCursor > ( emptyNextPageState ) ;
2130 }
2231
2332 return nextPageFuncGenerator ( createCursor ( nextCursorElement ) ) ;
@@ -27,14 +36,14 @@ internal static NextPageAsync<TData, TCursor> DetermineNextPageAsyncFunc<TData,
2736 Func < TCursor , NextPageAsync < TData , TCursor > > nextPageAsyncFuncGenerator ,
2837 Func < TDataEntry , TCursor > createCursor ,
2938 TDataEntry ? nextCursorElement ,
30- int ? totalCount ,
39+ EmptyNextPageStateAsync emptyNextPageState ,
3140 bool ? hasNextPage ,
3241 ComputeNextPage computeNextPage ) where TCursor : ICursor
3342 {
3443 if ( nextCursorElement == null
3544 || CanSkipNextPageCheck ( computeNextPage , hasNextPage ) )
3645 {
37- return EmptyNextPageAsync < TData , TCursor > ( totalCount ) ;
46+ return EmptyNextPageAsync < TData , TCursor > ( emptyNextPageState ) ;
3847 }
3948
4049 return nextPageAsyncFuncGenerator ( createCursor ( nextCursorElement ) ) ;
@@ -49,21 +58,36 @@ private static bool CanSkipNextPageCheck(
4958 && ! hasNextPage . Value ;
5059 }
5160
52- internal static NextPage < T , TCursor > EmptyNextPage < T , TCursor > ( int ? totalCount ) where TCursor : ICursor
61+ private static NextPage < T , TCursor > EmptyNextPage < T , TCursor > (
62+ EmptyNextPageState emptyNextPageState ) where TCursor : ICursor
5363 {
54- return ( ) => new PageResult < T , TCursor > ( [ ] , false , totalCount , EmptyNextPage < T , TCursor > ( totalCount ) , default ) ;
64+ return ( ) => new PageResult < T , TCursor > (
65+ [ ] ,
66+ hasNextPage : false ,
67+ emptyNextPageState . TotalCount ,
68+ EmptyNextPage < T , TCursor > ( emptyNextPageState ) ,
69+ nextCursor : default ,
70+ emptyNextPageState . HasPreviousPageFunc ) ;
5571 }
5672
57- internal static NextPageAsync < T , TCursor > EmptyNextPageAsync < T , TCursor > ( int ? totalCount ) where TCursor : ICursor
73+ private static NextPageAsync < T , TCursor > EmptyNextPageAsync < T , TCursor > (
74+ EmptyNextPageStateAsync emptyNextPageState ) where TCursor : ICursor
5875 {
59- return ( cancellationToken ) => Task . FromResult ( new PageResultAsync < T , TCursor > ( [ ] , false , totalCount , EmptyNextPageAsync < T , TCursor > ( totalCount ) , default ) ) ;
76+ return ( cancellationToken ) => Task . FromResult (
77+ new PageResultAsync < T , TCursor > (
78+ [ ] ,
79+ hasNextPage : false ,
80+ emptyNextPageState . TotalCount ,
81+ EmptyNextPageAsync < T , TCursor > ( emptyNextPageState ) ,
82+ nextCursor : default ,
83+ emptyNextPageState . HasPreviousPageAsyncFunc ) ) ;
6084 }
6185
6286 internal static bool ShouldComputeTotalCount ( bool hasAlreadyComputedCount , ComputeTotalCount totalEnum )
6387 {
6488 return ( hasAlreadyComputedCount , totalEnum ) switch
6589 {
66- ( false , ComputeTotalCount . Never ) => false ,
90+ ( _ , ComputeTotalCount . Never ) => false ,
6791 ( false , ComputeTotalCount . Once ) => true ,
6892 ( true , ComputeTotalCount . Once ) => false ,
6993 ( _, ComputeTotalCount . EveryPage ) => true ,
@@ -78,4 +102,26 @@ internal static void ThrowIfEnumNotDefined<T>(T argument, [CallerArgumentExpress
78102 throw new ArgumentException ( $ "Parameter '{ paramName } ' has invalid enum value '{ argument } '.", paramName ) ;
79103 }
80104 }
105+
106+ internal static ( T ? previousCursorElement , T ? nextCursorElement ) GetCursorElements < T > (
107+ List < T > pageData ,
108+ PaginationDirection paginationDirection )
109+ {
110+ return paginationDirection switch
111+ {
112+ PaginationDirection . Forward => ( pageData . FirstOrDefault ( ) , pageData . LastOrDefault ( ) ) ,
113+ PaginationDirection . Backward => ( pageData . LastOrDefault ( ) , pageData . FirstOrDefault ( ) ) ,
114+ _ => throw new ArgumentOutOfRangeException ( nameof ( paginationDirection ) ) ,
115+ } ;
116+ }
117+
118+ internal static PaginationDirection InvertDirection ( PaginationDirection paginationDirection )
119+ {
120+ return paginationDirection switch
121+ {
122+ PaginationDirection . Forward => PaginationDirection . Backward ,
123+ PaginationDirection . Backward => PaginationDirection . Forward ,
124+ _ => throw new ArgumentOutOfRangeException ( nameof ( paginationDirection ) ) ,
125+ } ;
126+ }
81127}
0 commit comments