Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions generators/csharp/base/src/asIs/Page.Template.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using global::System.Collections;
using global::System.Collections.ObjectModel;
using global::System.Net;

namespace <%= namespace%>;

Expand All @@ -19,11 +20,38 @@ public Page(IReadOnlyList<TItem> items)
Items = items;
}

/// <summary>
/// Creates a new <see cref="Page{TItem}"/> with the specified items and response metadata.
/// </summary>
public Page(IReadOnlyList<TItem> items, object? response, HttpStatusCode statusCode, ResponseHeaders? headers)
{
Items = items;
Response = response;
StatusCode = statusCode;
Headers = headers;
}

/// <summary>
/// Gets the items in this <see cref="Page{TItem}"/>.
/// </summary>
public IReadOnlyList<TItem> Items { get; }

/// <summary>
/// The full API response object for this page. Cast to the endpoint's response
/// type to access fields beyond the paginated items (e.g., TotalCount, metadata).
/// </summary>
public object? Response { get; }

/// <summary>
/// The HTTP status code of the response that produced this page.
/// </summary>
public HttpStatusCode StatusCode { get; }

/// <summary>
/// The HTTP response headers from the response that produced this page.
/// </summary>
public ResponseHeaders? Headers { get; }

/// <summary>
/// Enumerate the items in this <see cref="Page{TItem}"/>.
/// </summary>
Expand Down
44 changes: 25 additions & 19 deletions generators/csharp/base/src/asIs/Pager.Template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ internal sealed class OffsetPager<TRequest, TRequestOptions, TResponse, TOffset,
private readonly SendRequest _sendRequest;
private readonly ParseApiCallDelegate _parseApiCall;

internal delegate global::System.Threading.Tasks.Task<TResponse> SendRequest(
internal delegate global::System.Threading.Tasks.Task<WithRawResponse<TResponse>> SendRequest(
TRequest request,
TRequestOptions? options,
CancellationToken cancellationToken
Expand All @@ -109,7 +109,7 @@ private delegate (
TRequest? nextRequest,
bool hasNextPage,
Page<TItem> page
) ParseApiCallDelegate(TRequest request, TResponse response);
) ParseApiCallDelegate(TRequest request, WithRawResponse<TResponse> wrappedResponse);

public Page<TItem> CurrentPage { get; private set; }
public bool HasNextPage { get; private set; }
Expand Down Expand Up @@ -146,15 +146,15 @@ bool hasNextPage
)
{
request ??= Activator.CreateInstance<TRequest>();
var response = await sendRequest(request, options, cancellationToken).ConfigureAwait(false);
var wrappedResponse = await sendRequest(request, options, cancellationToken).ConfigureAwait(false);
var parseApiCall = CreateParseApiCallDelegate(
getItems,
getOffset,
setOffset,
getStep,
getHasNextPage
);
var (nextRequest, hasNextPage, page) = parseApiCall(request, response);
var (nextRequest, hasNextPage, page) = parseApiCall(request, wrappedResponse);
return new OffsetPager<TRequest, TRequestOptions, TResponse, TOffset, TStep, TItem>(
nextRequest,
options,
Expand All @@ -173,10 +173,10 @@ private static ParseApiCallDelegate CreateParseApiCallDelegate(
GetHasNextPage? getHasNextPage
)
{
return (request, response) =>
return (request, wrappedResponse) =>
ParseApiCall(
request,
response,
wrappedResponse,
getItems,
getOffset,
setOffset,
Expand All @@ -191,9 +191,9 @@ private static ParseApiCallDelegate CreateParseApiCallDelegate(
CancellationToken cancellationToken = default
)
{
var response = await _sendRequest(request, options, cancellationToken)
var wrappedResponse = await _sendRequest(request, options, cancellationToken)
.ConfigureAwait(false);
var (nextRequest, hasNextPageFlag, page) = _parseApiCall(request, response);
var (nextRequest, hasNextPageFlag, page) = _parseApiCall(request, wrappedResponse);
_request = nextRequest;
HasNextPage = hasNextPageFlag;
CurrentPage = page;
Expand All @@ -202,16 +202,19 @@ private static ParseApiCallDelegate CreateParseApiCallDelegate(

private static (TRequest? nextRequest, bool hasNextPage, Page<TItem> page) ParseApiCall(
TRequest request,
TResponse response,
WithRawResponse<TResponse> wrappedResponse,
GetItems getItems,
GetOffset getOffset,
SetOffset setOffset,
GetStep? getStep,
GetHasNextPage? getHasNextPage
)
{
var response = wrappedResponse.Data;
var items = getItems(response);
var page = items is not null ? new Page<TItem>(items) : Page<TItem>.Empty;
var page = items is not null
? new Page<TItem>(items, response, wrappedResponse.RawResponse.StatusCode, wrappedResponse.RawResponse.Headers)
: Page<TItem>.Empty;
var offset = getOffset(request);
var hasNextPage = getHasNextPage?.Invoke(response) ?? items?.Count > 0;
if (!hasNextPage)
Expand Down Expand Up @@ -350,7 +353,7 @@ internal sealed class CursorPager<TRequest, TRequestOptions, TResponse, TCursor,
/// <summary>
/// Delegate for sending a request.
/// </summary>
internal delegate global::System.Threading.Tasks.Task<TResponse> SendRequest(
internal delegate global::System.Threading.Tasks.Task<WithRawResponse<TResponse>> SendRequest(
TRequest request,
TRequestOptions? options,
CancellationToken cancellationToken
Expand All @@ -375,7 +378,7 @@ private delegate (
TRequest? nextRequest,
bool hasNextPage,
Page<TItem> page
) ParseApiCallDelegate(TRequest request, TResponse response);
) ParseApiCallDelegate(TRequest request, WithRawResponse<TResponse> wrappedResponse);

/// <summary>
/// The current <see cref="Page{TItem}"/>.
Expand Down Expand Up @@ -420,9 +423,9 @@ bool hasNextPage
)
{
request ??= Activator.CreateInstance<TRequest>();
var response = await sendRequest(request, options, cancellationToken).ConfigureAwait(false);
var wrappedResponse = await sendRequest(request, options, cancellationToken).ConfigureAwait(false);
var parseApiCall = CreateParseApiCallDelegate(getItems, getNextCursor, setCursor);
var (nextRequest, hasNextPage, page) = parseApiCall(request, response);
var (nextRequest, hasNextPage, page) = parseApiCall(request, wrappedResponse);
return new CursorPager<TRequest, TRequestOptions, TResponse, TCursor, TItem>(
nextRequest,
options,
Expand All @@ -439,13 +442,16 @@ private static ParseApiCallDelegate CreateParseApiCallDelegate(
SetCursor setCursor
)
{
return (request, response) =>
return (request, wrappedResponse) =>
{
var response = wrappedResponse.Data;
var items = getItems(response);
var page = items is not null ? new Page<TItem>(items) : Page<TItem>.Empty;
var page = items is not null
? new Page<TItem>(items, response, wrappedResponse.RawResponse.StatusCode, wrappedResponse.RawResponse.Headers)
: Page<TItem>.Empty;
var cursor = getNextCursor(response);
var hasNextPage = cursor switch
{
{
null or "" => false,
_ => true
};
Expand All @@ -465,9 +471,9 @@ SetCursor setCursor
CancellationToken cancellationToken = default
)
{
var response = await _sendRequest(request, options, cancellationToken)
var wrappedResponse = await _sendRequest(request, options, cancellationToken)
.ConfigureAwait(false);
var (nextRequest, hasNextPage, page) = _parseApiCall(request, response);
var (nextRequest, hasNextPage, page) = _parseApiCall(request, wrappedResponse);
_request = nextRequest;
HasNextPage = hasNextPage;
CurrentPage = page;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -46,7 +47,7 @@ public async SystemTask CursorPagerShouldWorkWithGuidCursors()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
(request, cursor) =>
{
Expand Down Expand Up @@ -101,4 +102,15 @@ private class Cursor
{
public required Guid? Next { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -41,7 +42,7 @@ public async SystemTask OffsetPagerShouldWorkWithHasNextPage()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
request => request?.Pagination?.Page ?? 0,
(request, offset) =>
Expand Down Expand Up @@ -89,4 +90,15 @@ private class Data
{
public IEnumerable<string>? Items { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -29,7 +30,7 @@ public async SystemTask OffsetPagerShouldWorkWithIntPage()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
request => request?.Pagination?.Page ?? 0,
(request, offset) =>
Expand Down Expand Up @@ -79,4 +80,15 @@ private class Data
{
public IEnumerable<string>? Items { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -29,7 +30,7 @@ public async SystemTask OffsetPagerShouldWorkWithLongPage()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
request => request?.Pagination?.Page ?? 0,
(request, offset) =>
Expand Down Expand Up @@ -76,4 +77,15 @@ private class Data
{
public IEnumerable<string>? Items { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -45,7 +46,7 @@ public async SystemTask CursorPagerShouldWorkWithStringCursor()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
(request, cursor) =>
{
Expand Down Expand Up @@ -103,4 +104,15 @@ private class Cursor
{
public required string? Next { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using global::System.Net;
using NUnit.Framework;
using SystemTask = global::System.Threading.Tasks.Task;
using <%= namespace%>.Core;
Expand Down Expand Up @@ -29,7 +30,7 @@ public async SystemTask OffsetPagerShouldWorkWithoutRequest()
(_, _, _) =>
{
responses.MoveNext();
return SystemTask.FromResult(responses.Current);
return SystemTask.FromResult(Wrap(responses.Current));
},
request => request?.Pagination?.Page ?? 0,
(request, offset) =>
Expand Down Expand Up @@ -79,4 +80,15 @@ private class Data
{
public IEnumerable<string>? Items { get; set; }
}

private static WithRawResponse<Response> Wrap(Response response) => new()
{
Data = response,
RawResponse = new RawResponse
{
StatusCode = HttpStatusCode.OK,
Url = new Uri("https://localhost"),
Headers = default,
},
};
}
Loading
Loading