112 lines
3.0 KiB
C#
112 lines
3.0 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
|
||
|
#nullable enable
|
||
|
namespace Aurora.Cursor
|
||
|
{
|
||
|
public enum SortDirection
|
||
|
{
|
||
|
Asc,
|
||
|
Desc,
|
||
|
}
|
||
|
|
||
|
public class Cursor<T> where T : ICursorObject
|
||
|
{
|
||
|
private CursorList<T> _list;
|
||
|
|
||
|
private string? _previousPageToken;
|
||
|
private string? _nextPageToken;
|
||
|
private int _pageSize;
|
||
|
private Func<KeyValuePair<string, T>, string> _sortDelgate;
|
||
|
private SortDirection _direction;
|
||
|
public Cursor(ref CursorList<T> list)
|
||
|
{
|
||
|
this._list = list;
|
||
|
this._previousPageToken = string.Empty;
|
||
|
this._nextPageToken = string.Empty;
|
||
|
this._pageSize = 10;
|
||
|
this._sortDelgate = delegate (KeyValuePair<string, T> item)
|
||
|
{
|
||
|
return item.Value.Id;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public CursorResult<T> GetNextPage()
|
||
|
{
|
||
|
List<KeyValuePair<string, T>> tmpList;
|
||
|
|
||
|
// Sort reference list
|
||
|
if (this._direction == SortDirection.Desc)
|
||
|
{
|
||
|
tmpList = this._list.OrderByDescending(this._sortDelgate).ToList();
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tmpList = this._list.OrderBy(this._sortDelgate).ToList();
|
||
|
}
|
||
|
|
||
|
if (tmpList == null)
|
||
|
{
|
||
|
throw new System.NullReferenceException();
|
||
|
}
|
||
|
|
||
|
int startIdx = 0;
|
||
|
if (!string.IsNullOrEmpty(this._nextPageToken))
|
||
|
{
|
||
|
// TODO find another way to index into the list that's not a regular array search
|
||
|
startIdx = tmpList.FindIndex(item => item.Key == this._nextPageToken);
|
||
|
}
|
||
|
|
||
|
int endIdx = startIdx + this._pageSize;
|
||
|
|
||
|
List<T> selection = new List<T>();
|
||
|
|
||
|
// Get page
|
||
|
for (int i = startIdx; i < tmpList.Count && i < endIdx; i++)
|
||
|
{
|
||
|
selection.Add(tmpList.ElementAt(i).Value);
|
||
|
}
|
||
|
|
||
|
return new CursorResult<T>
|
||
|
{
|
||
|
NextPageToken = selection[selection.Count - 1].Id,
|
||
|
PrevPageToken = selection[0].Id,
|
||
|
Count = this._list.Count,
|
||
|
Result = selection
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public CursorResult<T> GetPreviousPage()
|
||
|
{
|
||
|
throw new NotImplementedException();
|
||
|
}
|
||
|
|
||
|
public Cursor<T> WithNextPage(string nextPageToken)
|
||
|
{
|
||
|
this._nextPageToken = nextPageToken;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public Cursor<T> WithPreviousPage(string prevPageToken)
|
||
|
{
|
||
|
this._previousPageToken = prevPageToken;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public Cursor<T> WithSort(Func<KeyValuePair<string, T>, string> sortDelegate, SortDirection direction)
|
||
|
{
|
||
|
this._sortDelgate = sortDelegate;
|
||
|
this._direction = direction;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public Cursor<T> WithSize(int size)
|
||
|
{
|
||
|
this._pageSize = size;
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|