using System; using System.Collections.Generic; using System.Linq; #nullable enable namespace Aurora.Cursor { public enum SortDirection { Asc, Desc, } public class Cursor where T : ICursorObject { private CursorList _list; private string? _previousPageToken; private string? _nextPageToken; private int _pageSize; private Func, string> _sortDelgate; private SortDirection _direction; public Cursor(ref CursorList list) { this._list = list; this._previousPageToken = string.Empty; this._nextPageToken = string.Empty; this._pageSize = 10; this._sortDelgate = delegate (KeyValuePair item) { return item.Key; }; } public CursorResult GetNextPage() { if (this._pageSize < 0) { throw new InvalidOperationException("Page Size must be greater than zero"); } List> 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> selection = new List>(); if (adjustedSize != 0) { selection = tmpList.GetRange(startIdx, adjustedSize); } return new CursorResult { 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 GetPreviousPage() { throw new NotImplementedException(); } public Cursor WithNextPageToken(string nextPageToken) { this._nextPageToken = nextPageToken; return this; } public Cursor WithPreviousPageToken(string prevPageToken) { this._previousPageToken = prevPageToken; return this; } public Cursor WithSort(Func, string> sortDelegate, SortDirection direction) { this._sortDelgate = sortDelegate; this._direction = direction; return this; } public Cursor WithSort(string key, SortDirection direction) { this._sortDelgate = (item) => key; this._direction = direction; return this; } public Cursor WithSize(int size) { this._pageSize = size; return this; } } }