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; } } }