using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace MCPForUnity.Editor.Helpers { /// /// Standard pagination request for all paginated tool operations. /// Provides consistent handling of page_size/pageSize and cursor/page_number parameters. /// public class PaginationRequest { /// /// Number of items per page. Default is 50. /// public int PageSize { get; set; } = 50; /// /// 0-based cursor position for the current page. /// public int Cursor { get; set; } = 0; /// /// 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. /// 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 }; } } /// /// Standard pagination response for all paginated tool operations. /// Provides consistent response structure across all tools. /// /// The type of items in the paginated list public class PaginationResponse { /// /// The items on the current page. /// [JsonProperty("items")] public List Items { get; set; } = new List(); /// /// The cursor position for the current page (0-based). /// [JsonProperty("cursor")] public int Cursor { get; set; } /// /// The cursor for the next page, or null if this is the last page. /// [JsonProperty("nextCursor")] public int? NextCursor { get; set; } /// /// Total number of items across all pages. /// [JsonProperty("totalCount")] public int TotalCount { get; set; } /// /// Number of items per page. /// [JsonProperty("pageSize")] public int PageSize { get; set; } /// /// Whether there are more items after this page. /// [JsonProperty("hasMore")] public bool HasMore => NextCursor.HasValue; /// /// Creates a PaginationResponse from a full list of items and pagination parameters. /// /// The full list of items to paginate /// The pagination request parameters /// A paginated response with the appropriate slice of items public static PaginationResponse Create(IList 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(); 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 { Items = items, Cursor = cursor, NextCursor = nextCursor, TotalCount = totalCount, PageSize = pageSize }; } } }