using MongoDB.Driver; using MongoDB.Entities; using System.Linq.Expressions; namespace PrivaPub.Api.Mastodon.Infrastructure { public sealed record Page(string MaxId, string SinceId, string MinId, int Limit) { public static Page From(MastodonParams parameters, int limit) => new(parameters.Get("max_id"), parameters.Get("since_id"), parameters.Get("min_id"), limit); public async Task> Fetch(Find query, Expression> id, CancellationToken token) where T : IEntity { var field = new ExpressionFieldDefinition(id); if (!string.IsNullOrEmpty(MaxId)) query.Match(Builders.Filter.Lt(field, MaxId)); if (!string.IsNullOrEmpty(SinceId)) query.Match(Builders.Filter.Gt(field, SinceId)); if (!string.IsNullOrEmpty(MinId)) query.Match(Builders.Filter.Gt(field, MinId)); var ascending = !string.IsNullOrEmpty(MinId); var sortField = new ExpressionFieldDefinition(Expression.Lambda>(Expression.Convert(id.Body, typeof(object)), id.Parameters)); var items = await query.Sort(s => ascending ? s.Ascending(sortField) : s.Descending(sortField)).Limit(Limit).ExecuteAsync(token); if (ascending) items.Reverse(); return items; } } }