150 lines
5.0 KiB
C#
150 lines
5.0 KiB
C#
using System.Collections.Generic;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace MCPForUnity.Editor.Helpers
|
|
{
|
|
/// <summary>
|
|
/// Standard pagination request for all paginated tool operations.
|
|
/// Provides consistent handling of page_size/pageSize and cursor/page_number parameters.
|
|
/// </summary>
|
|
public class PaginationRequest
|
|
{
|
|
/// <summary>
|
|
/// Number of items per page. Default is 50.
|
|
/// </summary>
|
|
public int PageSize { get; set; } = 50;
|
|
|
|
/// <summary>
|
|
/// 0-based cursor position for the current page.
|
|
/// </summary>
|
|
public int Cursor { get; set; } = 0;
|
|
|
|
/// <summary>
|
|
/// Creates a PaginationRequest from JObject parameters.
|
|
/// Accepts both snake_case and camelCase parameter names for flexibility.
|
|
/// Converts 1-based page_number to 0-based cursor if needed.
|
|
/// </summary>
|
|
public static PaginationRequest FromParams(JObject @params, int defaultPageSize = 50)
|
|
{
|
|
if (@params == null)
|
|
return new PaginationRequest { PageSize = defaultPageSize };
|
|
|
|
// Accept both page_size and pageSize
|
|
int pageSize = ParamCoercion.CoerceInt(
|
|
@params["page_size"] ?? @params["pageSize"],
|
|
defaultPageSize
|
|
);
|
|
|
|
// Accept both cursor (0-based) and page_number (convert 1-based to 0-based)
|
|
var cursorToken = @params["cursor"];
|
|
var pageNumberToken = @params["page_number"] ?? @params["pageNumber"];
|
|
|
|
int cursor;
|
|
if (cursorToken != null)
|
|
{
|
|
cursor = ParamCoercion.CoerceInt(cursorToken, 0);
|
|
}
|
|
else if (pageNumberToken != null)
|
|
{
|
|
// Convert 1-based page_number to 0-based cursor
|
|
int pageNumber = ParamCoercion.CoerceInt(pageNumberToken, 1);
|
|
cursor = (pageNumber - 1) * pageSize;
|
|
if (cursor < 0) cursor = 0;
|
|
}
|
|
else
|
|
{
|
|
cursor = 0;
|
|
}
|
|
|
|
return new PaginationRequest
|
|
{
|
|
PageSize = pageSize > 0 ? pageSize : defaultPageSize,
|
|
Cursor = cursor
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Standard pagination response for all paginated tool operations.
|
|
/// Provides consistent response structure across all tools.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of items in the paginated list</typeparam>
|
|
public class PaginationResponse<T>
|
|
{
|
|
/// <summary>
|
|
/// The items on the current page.
|
|
/// </summary>
|
|
[JsonProperty("items")]
|
|
public List<T> Items { get; set; } = new List<T>();
|
|
|
|
/// <summary>
|
|
/// The cursor position for the current page (0-based).
|
|
/// </summary>
|
|
[JsonProperty("cursor")]
|
|
public int Cursor { get; set; }
|
|
|
|
/// <summary>
|
|
/// The cursor for the next page, or null if this is the last page.
|
|
/// </summary>
|
|
[JsonProperty("nextCursor")]
|
|
public int? NextCursor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Total number of items across all pages.
|
|
/// </summary>
|
|
[JsonProperty("totalCount")]
|
|
public int TotalCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Number of items per page.
|
|
/// </summary>
|
|
[JsonProperty("pageSize")]
|
|
public int PageSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Whether there are more items after this page.
|
|
/// </summary>
|
|
[JsonProperty("hasMore")]
|
|
public bool HasMore => NextCursor.HasValue;
|
|
|
|
/// <summary>
|
|
/// Creates a PaginationResponse from a full list of items and pagination parameters.
|
|
/// </summary>
|
|
/// <param name="allItems">The full list of items to paginate</param>
|
|
/// <param name="request">The pagination request parameters</param>
|
|
/// <returns>A paginated response with the appropriate slice of items</returns>
|
|
public static PaginationResponse<T> Create(IList<T> allItems, PaginationRequest request)
|
|
{
|
|
int totalCount = allItems.Count;
|
|
int cursor = request.Cursor;
|
|
int pageSize = request.PageSize;
|
|
|
|
// Clamp cursor to valid range
|
|
if (cursor < 0) cursor = 0;
|
|
if (cursor > totalCount) cursor = totalCount;
|
|
|
|
// Get the page of items
|
|
var items = new List<T>();
|
|
int endIndex = System.Math.Min(cursor + pageSize, totalCount);
|
|
for (int i = cursor; i < endIndex; i++)
|
|
{
|
|
items.Add(allItems[i]);
|
|
}
|
|
|
|
// Calculate next cursor
|
|
int? nextCursor = endIndex < totalCount ? endIndex : (int?)null;
|
|
|
|
return new PaginationResponse<T>
|
|
{
|
|
Items = items,
|
|
Cursor = cursor,
|
|
NextCursor = nextCursor,
|
|
TotalCount = totalCount,
|
|
PageSize = pageSize
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|