126 lines
3.6 KiB
C#
126 lines
3.6 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.Key;
|
|
};
|
|
}
|
|
|
|
public CursorResult<T> GetNextPage()
|
|
{
|
|
if (this._pageSize < 0)
|
|
{
|
|
throw new InvalidOperationException("Page Size must be greater than zero");
|
|
}
|
|
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) + 1;
|
|
}
|
|
|
|
int adjustedSize = this._pageSize;
|
|
if (startIdx + this._pageSize > tmpList.Count)
|
|
{
|
|
adjustedSize = this._pageSize - ((startIdx + _pageSize) - tmpList.Count);
|
|
}
|
|
|
|
|
|
List<KeyValuePair<string, T>> selection = new List<KeyValuePair<string, T>>();
|
|
if (adjustedSize != 0)
|
|
{
|
|
selection = tmpList.GetRange(startIdx, adjustedSize);
|
|
}
|
|
|
|
return new CursorResult<T>
|
|
{
|
|
NextPageToken = this._pageSize == selection.Count ? selection[selection.Count - 1].Key : string.Empty,
|
|
PrevPageToken = string.Empty,
|
|
Count = this._list.Count,
|
|
Result = selection.ConvertAll(item => item.Value)
|
|
};
|
|
}
|
|
|
|
public CursorResult<T> GetPreviousPage()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public Cursor<T> WithNextPageToken(string nextPageToken)
|
|
{
|
|
this._nextPageToken = nextPageToken;
|
|
return this;
|
|
}
|
|
|
|
public Cursor<T> WithPreviousPageToken(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> WithSort(string key, SortDirection direction)
|
|
{
|
|
this._sortDelgate = (item) => key;
|
|
this._direction = direction;
|
|
return this;
|
|
}
|
|
|
|
public Cursor<T> WithSize(int size)
|
|
{
|
|
this._pageSize = size;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
} |