| | | 1 | | namespace TeleFlow.Telegram.Internal.Handlers; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Stores route filters in the order the dispatcher actually evaluates them so handler selection does not |
| | | 5 | | /// split built-in filters, custom filters, and role requirements on every incoming Telegram update. |
| | | 6 | | /// </summary> |
| | | 7 | | internal sealed class TelegramRouteFilterPlan |
| | | 8 | | { |
| | 1 | 9 | | private static readonly IReadOnlyList<TelegramFilterDescriptor> EmptyBuiltInFilters = []; |
| | 1 | 10 | | private static readonly IReadOnlyList<TelegramCustomFilterCallSite> EmptyCustomFilters = []; |
| | 1 | 11 | | private static readonly IReadOnlyList<TelegramRoleRequirementDescriptor> EmptyRoleRequirements = []; |
| | 1 | 12 | | private static readonly TelegramRouteFilterPlan Empty = new( |
| | 1 | 13 | | EmptyBuiltInFilters, |
| | 1 | 14 | | EmptyCustomFilters, |
| | 1 | 15 | | EmptyRoleRequirements); |
| | | 16 | | |
| | | 17 | | private TelegramRouteFilterPlan( |
| | | 18 | | IReadOnlyList<TelegramFilterDescriptor> builtInFilters, |
| | | 19 | | IReadOnlyList<TelegramCustomFilterCallSite> customFilters, |
| | | 20 | | IReadOnlyList<TelegramRoleRequirementDescriptor> roleRequirements) |
| | | 21 | | { |
| | | 22 | | BuiltInFilters = builtInFilters; |
| | | 23 | | CustomFilters = customFilters; |
| | | 24 | | RoleRequirements = roleRequirements; |
| | 430 | 25 | | } |
| | | 26 | | |
| | | 27 | | public IReadOnlyList<TelegramFilterDescriptor> BuiltInFilters { get; } |
| | | 28 | | |
| | | 29 | | public IReadOnlyList<TelegramCustomFilterCallSite> CustomFilters { get; } |
| | | 30 | | |
| | | 31 | | public IReadOnlyList<TelegramRoleRequirementDescriptor> RoleRequirements { get; } |
| | | 32 | | |
| | | 33 | | public static TelegramRouteFilterPlan Create(TelegramRouteDescriptor route) |
| | | 34 | | { |
| | 1092 | 35 | | ArgumentNullException.ThrowIfNull(route); |
| | | 36 | | |
| | 1092 | 37 | | return Create(route.Kind, route.Filters, route.RoleRequirements); |
| | | 38 | | } |
| | | 39 | | |
| | | 40 | | private static TelegramRouteFilterPlan Create( |
| | | 41 | | TelegramHandlerKind handlerKind, |
| | | 42 | | IReadOnlyList<TelegramFilterDescriptor> filters, |
| | | 43 | | IReadOnlyList<TelegramRoleRequirementDescriptor> roleRequirements) |
| | | 44 | | { |
| | 1092 | 45 | | ArgumentNullException.ThrowIfNull(filters); |
| | 1092 | 46 | | ArgumentNullException.ThrowIfNull(roleRequirements); |
| | | 47 | | |
| | 1092 | 48 | | if (filters.Count == 0 && roleRequirements.Count == 0) |
| | | 49 | | { |
| | 663 | 50 | | return Empty; |
| | | 51 | | } |
| | | 52 | | |
| | 429 | 53 | | List<TelegramFilterDescriptor>? builtInFilters = null; |
| | 429 | 54 | | List<TelegramCustomFilterCallSite>? customFilters = null; |
| | | 55 | | |
| | 2106 | 56 | | for (var index = 0; index < filters.Count; index++) |
| | | 57 | | { |
| | 624 | 58 | | var filter = filters[index]; |
| | | 59 | | |
| | 624 | 60 | | if (filter.CustomFilterType is { } customFilterType) |
| | | 61 | | { |
| | 61 | 62 | | customFilters ??= []; |
| | 61 | 63 | | customFilters.Add(TelegramCustomFilterCallSite.Create( |
| | 61 | 64 | | customFilterType, |
| | 61 | 65 | | filter.CustomFilterContextType, |
| | 61 | 66 | | filter.CustomFilterAttribute, |
| | 61 | 67 | | handlerKind)); |
| | 61 | 68 | | continue; |
| | | 69 | | } |
| | | 70 | | |
| | 563 | 71 | | builtInFilters ??= []; |
| | 563 | 72 | | builtInFilters.Add(filter); |
| | | 73 | | } |
| | | 74 | | |
| | 429 | 75 | | return new TelegramRouteFilterPlan( |
| | 429 | 76 | | builtInFilters?.ToArray() ?? EmptyBuiltInFilters, |
| | 429 | 77 | | customFilters?.ToArray() ?? EmptyCustomFilters, |
| | 429 | 78 | | roleRequirements); |
| | | 79 | | } |
| | | 80 | | } |