3 Commits

Author SHA1 Message Date
Rikitav 0dedd3c0f4 * warnings fixes 2026-03-09 13:40:58 +04:00
Rikitav 79d5df8291 * Syntaxual refactoring 2026-03-09 13:23:21 +04:00
Rikitav 899243c62b * Added default state storage registering
* Added extension method for replacing default state storage
2026-03-09 13:10:49 +04:00
143 changed files with 9760 additions and 9862 deletions
@@ -148,6 +148,7 @@ public class ImplicitHandlerBuilderExtensionsGenerator : IIncrementalGenerator
.AddMembers([.. targetters.Values, .. extensions]); .AddMembers([.. targetters.Values, .. extensions]);
NamespaceDeclarationSyntax namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName("Telegrator")) NamespaceDeclarationSyntax namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName("Telegrator"))
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable CS1591"))
.WithMembers([extensionsClass]); .WithMembers([extensionsClass]);
CompilationUnitSyntax compilationUnit = SyntaxFactory.CompilationUnit() CompilationUnitSyntax compilationUnit = SyntaxFactory.CompilationUnit()
+10 -2
View File
@@ -221,7 +221,7 @@
<member name="T:Telegrator.Providers.HostAwaitingProvider"> <member name="T:Telegrator.Providers.HostAwaitingProvider">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="M:Telegrator.Providers.HostAwaitingProvider.#ctor(Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions},Microsoft.Extensions.Logging.ILogger{Telegrator.Providers.HostAwaitingProvider})"> <member name="M:Telegrator.Providers.HostAwaitingProvider.#ctor(Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions})">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="T:Telegrator.Providers.HostHandlersCollection"> <member name="T:Telegrator.Providers.HostHandlersCollection">
@@ -239,7 +239,7 @@
<member name="T:Telegrator.Providers.HostHandlersProvider"> <member name="T:Telegrator.Providers.HostHandlersProvider">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="M:Telegrator.Providers.HostHandlersProvider.#ctor(Telegrator.Core.IHandlersCollection,Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions},System.IServiceProvider,Microsoft.Extensions.Logging.ILogger{Telegrator.Providers.HostHandlersProvider})"> <member name="M:Telegrator.Providers.HostHandlersProvider.#ctor(Telegrator.Core.IHandlersCollection,Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions},System.IServiceProvider)">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="M:Telegrator.Providers.HostHandlersProvider.GetHandlerInstance(Telegrator.Core.Descriptors.HandlerDescriptor,System.Threading.CancellationToken)"> <member name="M:Telegrator.Providers.HostHandlersProvider.GetHandlerInstance(Telegrator.Core.Descriptors.HandlerDescriptor,System.Threading.CancellationToken)">
@@ -274,6 +274,14 @@
Provides method to configure Telegram Bot Host Provides method to configure Telegram Bot Host
</summary> </summary>
</member> </member>
<member name="M:Telegrator.ServicesCollectionExtensions.AddStateStorage``1(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
<summary>
Registers <see cref="T:Telegrator.Core.States.IStateStorage"/> service
</summary>
<typeparam name="TStorage"></typeparam>
<param name="services"></param>
<returns></returns>
</member>
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegramBotHostDefaults(Microsoft.Extensions.DependencyInjection.IServiceCollection)"> <member name="M:Telegrator.ServicesCollectionExtensions.AddTelegramBotHostDefaults(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
<summary> <summary>
Registers <see cref="T:Telegrator.Hosting.TelegramBotHost"/> default services Registers <see cref="T:Telegrator.Hosting.TelegramBotHost"/> default services
+5
View File
@@ -7161,6 +7161,11 @@
Provides extension methods for working with Telegram Update objects. Provides extension methods for working with Telegram Update objects.
</summary> </summary>
</member> </member>
<member name="M:Telegrator.UpdateExtensions.GetUserLanguageCode(Telegram.Bot.Types.Update)">
<summary>
Extracts the IETF language tag of the user's client from the update.
</summary>
</member>
<member name="M:Telegrator.UpdateExtensions.GetSenderId(Telegram.Bot.Types.Update)"> <member name="M:Telegrator.UpdateExtensions.GetSenderId(Telegram.Bot.Types.Update)">
<summary> <summary>
Selects from Update an object from which you can get the sender's ID Selects from Update an object from which you can get the sender's ID
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
@@ -15,7 +15,7 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<Title>Telegrator.RedisStateStorage</Title> <Title>Telegrator.RedisStateStorage</Title>
<Version>1.16.4</Version> <Version>1.16.5</Version>
<Authors>Rikitav Tim4ik</Authors> <Authors>Rikitav Tim4ik</Authors>
<Company>Rikitav Tim4ik</Company> <Company>Rikitav Tim4ik</Company>
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl> <RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
@@ -31,7 +31,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="StackExchange.Redis" Version="2.11.8 " /> <PackageReference Include="StackExchange.Redis" Version="2.11.8" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -9,3 +9,4 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0090")] [assembly: SuppressMessage("Style", "IDE0090")]
[assembly: SuppressMessage("Usage", "CA2254")] [assembly: SuppressMessage("Usage", "CA2254")]
[assembly: SuppressMessage("Maintainability", "CA1510")] [assembly: SuppressMessage("Maintainability", "CA1510")]
[assembly: SuppressMessage("Style", "IDE0270")]
@@ -7,13 +7,13 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Telegrator.Core; using Telegrator.Core;
namespace Telegrator.Hosting.Web namespace Telegrator.Hosting.Web;
/// <summary>
/// Represents a web hosted telegram bot
/// </summary>
public class TelegramBotWebHost : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
{ {
/// <summary>
/// Represents a web hosted telegram bot
/// </summary>
public class TelegramBotWebHost : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
{
private readonly WebApplication _innerApp; private readonly WebApplication _innerApp;
private readonly IUpdateRouter _updateRouter; private readonly IUpdateRouter _updateRouter;
private readonly ILogger<TelegramBotWebHost> _logger; private readonly ILogger<TelegramBotWebHost> _logger;
@@ -156,5 +156,4 @@ namespace Telegrator.Hosting.Web
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
_disposed = true; _disposed = true;
} }
}
} }
@@ -7,13 +7,13 @@ using Microsoft.Extensions.Logging;
using Telegrator.Core; using Telegrator.Core;
#pragma warning disable IDE0001 #pragma warning disable IDE0001
namespace Telegrator.Hosting.Web namespace Telegrator.Hosting.Web;
/// <summary>
/// Represents a web hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
/// </summary>
public class TelegramBotWebHostBuilder : IHostApplicationBuilder, ICollectingProvider
{ {
/// <summary>
/// Represents a web hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
/// </summary>
public class TelegramBotWebHostBuilder : IHostApplicationBuilder, ICollectingProvider
{
private readonly WebApplicationBuilder _innerBuilder; private readonly WebApplicationBuilder _innerBuilder;
private readonly WebApplicationOptions _settings; private readonly WebApplicationOptions _settings;
internal IHandlersCollection _handlers = null!; internal IHandlersCollection _handlers = null!;
@@ -111,5 +111,4 @@ namespace Telegrator.Hosting.Web
{ {
((IHostApplicationBuilder)_innerBuilder).ConfigureContainer(factory, configure); ((IHostApplicationBuilder)_innerBuilder).ConfigureContainer(factory, configure);
} }
}
} }
@@ -1,13 +1,13 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace Telegrator.Hosting.Web namespace Telegrator.Hosting.Web;
/// <summary>
/// Configuration options for Telegram bot behavior and execution settings.
/// Controls various aspects of bot operation including concurrency, routing, webhook receiving, and execution policies.
/// </summary>
public class WebhookerOptions
{ {
/// <summary>
/// Configuration options for Telegram bot behavior and execution settings.
/// Controls various aspects of bot operation including concurrency, routing, webhook receiving, and execution policies.
/// </summary>
public class WebhookerOptions
{
/// <summary> /// <summary>
/// Gets or sets HTTPS URL to send updates to. Use an empty string to remove webhook integration /// Gets or sets HTTPS URL to send updates to. Use an empty string to remove webhook integration
/// </summary> /// </summary>
@@ -31,5 +31,4 @@ namespace Telegrator.Hosting.Web
/// Pass true to drop all pending updates /// Pass true to drop all pending updates
/// </summary> /// </summary>
public bool DropPendingUpdates { get; set; } = false; public bool DropPendingUpdates { get; set; } = false;
}
} }
@@ -10,13 +10,13 @@ using Telegram.Bot.Types;
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Hosting.Web; using Telegrator.Hosting.Web;
namespace Telegrator.Mediation namespace Telegrator.Mediation;
/// <summary>
/// Service for receiving updates for Hosted telegram bots via Webhooks
/// </summary>
public class HostedUpdateWebhooker : IHostedService
{ {
/// <summary>
/// Service for receiving updates for Hosted telegram bots via Webhooks
/// </summary>
public class HostedUpdateWebhooker : IHostedService
{
private const string SecretTokenHeader = "X-Telegram-Bot-Api-Secret-Token"; private const string SecretTokenHeader = "X-Telegram-Bot-Api-Secret-Token";
private readonly IEndpointRouteBuilder _botHost; private readonly IEndpointRouteBuilder _botHost;
@@ -93,5 +93,4 @@ namespace Telegrator.Mediation
await _updateRouter.HandleUpdateAsync(_botClient, update, ctx.RequestAborted); await _updateRouter.HandleUpdateAsync(_botClient, update, ctx.RequestAborted);
return Results.Ok(); return Results.Ok();
} }
}
} }
@@ -15,7 +15,7 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<Title>Telegrator.Hosting.Web</Title> <Title>Telegrator.Hosting.Web</Title>
<Version>1.16.4</Version> <Version>1.16.5</Version>
<Authors>Rikitav Tim4ik</Authors> <Authors>Rikitav Tim4ik</Authors>
<Company>Rikitav Tim4ik</Company> <Company>Rikitav Tim4ik</Company>
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl> <RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
@@ -9,3 +9,4 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0090")] [assembly: SuppressMessage("Style", "IDE0090")]
[assembly: SuppressMessage("Usage", "CA2254")] [assembly: SuppressMessage("Usage", "CA2254")]
[assembly: SuppressMessage("Maintainability", "CA1510")] [assembly: SuppressMessage("Maintainability", "CA1510")]
[assembly: SuppressMessage("Style", "IDE0270")]
@@ -3,17 +3,17 @@ using Telegram.Bot;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core; using Telegrator.Core;
namespace Telegrator.Hosting namespace Telegrator.Hosting;
/// <summary>
/// Implementation of <see cref="ITelegramBotInfo"/> that provides bot information.
/// Contains metadata about the Telegram bot including user details and service provider for wider filterring abilities
/// </summary>
/// <param name="client"></param>
/// <param name="services"></param>
/// <param name="configuration"></param>
public class HostedTelegramBotInfo(ITelegramBotClient client, IServiceProvider services, IConfiguration configuration) : ITelegramBotInfo
{ {
/// <summary>
/// Implementation of <see cref="ITelegramBotInfo"/> that provides bot information.
/// Contains metadata about the Telegram bot including user details and service provider for wider filterring abilities
/// </summary>
/// <param name="client"></param>
/// <param name="services"></param>
/// <param name="configuration"></param>
public class HostedTelegramBotInfo(ITelegramBotClient client, IServiceProvider services, IConfiguration configuration) : ITelegramBotInfo
{
/// <inheritdoc/> /// <inheritdoc/>
public User User { get; } = client.GetMe().Result; public User User { get; } = client.GetMe().Result;
@@ -26,5 +26,4 @@ namespace Telegrator.Hosting
/// Provides access to configuration of this Hosted telegram bot /// Provides access to configuration of this Hosted telegram bot
/// </summary> /// </summary>
public IConfiguration Configuration { get; } = configuration; public IConfiguration Configuration { get; } = configuration;
}
} }
@@ -3,13 +3,13 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Telegrator.Core; using Telegrator.Core;
namespace Telegrator.Hosting namespace Telegrator.Hosting;
/// <summary>
/// Represents a hosted telegram bot
/// </summary>
public class TelegramBotHost : IHost, ITelegratorBot
{ {
/// <summary>
/// Represents a hosted telegram bot
/// </summary>
public class TelegramBotHost : IHost, ITelegratorBot
{
private readonly IHost _innerHost; private readonly IHost _innerHost;
private readonly IUpdateRouter _updateRouter; private readonly IUpdateRouter _updateRouter;
private readonly ILogger<TelegramBotHost> _logger; private readonly ILogger<TelegramBotHost> _logger;
@@ -111,5 +111,4 @@ namespace Telegrator.Hosting
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
_disposed = true; _disposed = true;
} }
}
} }
@@ -3,18 +3,16 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Diagnostics.Metrics;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Providers;
#pragma warning disable IDE0001 #pragma warning disable IDE0001
namespace Telegrator.Hosting namespace Telegrator.Hosting;
/// <summary>
/// Represents a hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
/// </summary>
public class TelegramBotHostBuilder : IHostApplicationBuilder, ICollectingProvider
{ {
/// <summary>
/// Represents a hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
/// </summary>
public class TelegramBotHostBuilder : IHostApplicationBuilder, ICollectingProvider
{
private readonly HostApplicationBuilder _innerBuilder; private readonly HostApplicationBuilder _innerBuilder;
private readonly HostApplicationBuilderSettings _settings; private readonly HostApplicationBuilderSettings _settings;
internal IHandlersCollection _handlers = null!; internal IHandlersCollection _handlers = null!;
@@ -112,5 +110,4 @@ namespace Telegrator.Hosting
{ {
this.ConfigureContainer(factory, configure); this.ConfigureContainer(factory, configure);
} }
}
} }
@@ -1,20 +1,18 @@
using Microsoft.Extensions.Logging; namespace Telegrator.Logging;
namespace Telegrator.Logging /// <summary>
/// Adapter for Microsoft.Extensions.Logging to work with Telegrator logging system.
/// This allows seamless integration with ASP.NET Core logging infrastructure.
/// </summary>
public class MicrosoftLoggingAdapter : ITelegratorLogger
{ {
/// <summary> private readonly Microsoft.Extensions.Logging.ILogger _logger;
/// Adapter for Microsoft.Extensions.Logging to work with Telegrator logging system.
/// This allows seamless integration with ASP.NET Core logging infrastructure.
/// </summary>
public class MicrosoftLoggingAdapter : ITelegratorLogger
{
private readonly ILogger _logger;
/// <summary> /// <summary>
/// Initializes a new instance of MicrosoftLoggingAdapter. /// Initializes a new instance of MicrosoftLoggingAdapter.
/// </summary> /// </summary>
/// <param name="logger">The Microsoft.Extensions.Logging logger instance.</param> /// <param name="logger">The Microsoft.Extensions.Logging logger instance.</param>
public MicrosoftLoggingAdapter(ILogger logger) public MicrosoftLoggingAdapter(Microsoft.Extensions.Logging.ILogger logger)
{ {
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); _logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
@@ -24,11 +22,11 @@ namespace Telegrator.Logging
{ {
var msLogLevel = level switch var msLogLevel = level switch
{ {
Telegrator.Logging.LogLevel.Trace => Microsoft.Extensions.Logging.LogLevel.Trace, LogLevel.Trace => Microsoft.Extensions.Logging.LogLevel.Trace,
Telegrator.Logging.LogLevel.Debug => Microsoft.Extensions.Logging.LogLevel.Debug, LogLevel.Debug => Microsoft.Extensions.Logging.LogLevel.Debug,
Telegrator.Logging.LogLevel.Information => Microsoft.Extensions.Logging.LogLevel.Information, LogLevel.Information => Microsoft.Extensions.Logging.LogLevel.Information,
Telegrator.Logging.LogLevel.Warning => Microsoft.Extensions.Logging.LogLevel.Warning, LogLevel.Warning => Microsoft.Extensions.Logging.LogLevel.Warning,
Telegrator.Logging.LogLevel.Error => Microsoft.Extensions.Logging.LogLevel.Error, LogLevel.Error => Microsoft.Extensions.Logging.LogLevel.Error,
_ => Microsoft.Extensions.Logging.LogLevel.Information _ => Microsoft.Extensions.Logging.LogLevel.Information
}; };
@@ -41,5 +39,4 @@ namespace Telegrator.Logging
_logger.Log(msLogLevel, default, message, null, (str, _) => str); _logger.Log(msLogLevel, default, message, null, (str, _) => str);
} }
} }
}
} }
@@ -7,11 +7,11 @@ using Telegrator.Core;
using Telegrator.Core.States; using Telegrator.Core.States;
using Telegrator.Mediation; using Telegrator.Mediation;
namespace Telegrator.Polling namespace Telegrator.Polling;
/// <inheritdoc/>
public class HostUpdateRouter : UpdateRouter
{ {
/// <inheritdoc/>
public class HostUpdateRouter : UpdateRouter
{
/// <summary> /// <summary>
/// <see cref="ILogger"/> of this router /// <see cref="ILogger"/> of this router
/// </summary> /// </summary>
@@ -56,5 +56,4 @@ namespace Telegrator.Polling
Logger.LogError("Exception was thrown during update routing faulted :\n{exception}", exception.ToString()); Logger.LogError("Exception was thrown during update routing faulted :\n{exception}", exception.ToString());
} }
}
} }
@@ -6,17 +6,17 @@ using Telegram.Bot.Polling;
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Mediation; using Telegrator.Mediation;
namespace Telegrator.Polling namespace Telegrator.Polling;
/// <summary>
/// Service for receiving updates for Hosted telegram bots
/// </summary>
/// <param name="botClient"></param>
/// <param name="updateRouter"></param>
/// <param name="options"></param>
/// <param name="logger"></param>
public class HostedUpdateReceiver(ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<ReceiverOptions> options, ILogger<HostedUpdateReceiver> logger) : BackgroundService
{ {
/// <summary>
/// Service for receiving updates for Hosted telegram bots
/// </summary>
/// <param name="botClient"></param>
/// <param name="updateRouter"></param>
/// <param name="options"></param>
/// <param name="logger"></param>
public class HostedUpdateReceiver(ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<ReceiverOptions> options, ILogger<HostedUpdateReceiver> logger) : BackgroundService
{
private readonly ReceiverOptions _receiverOptions = options.Value; private readonly ReceiverOptions _receiverOptions = options.Value;
private readonly IUpdateRouter _updateRouter = updateRouter; private readonly IUpdateRouter _updateRouter = updateRouter;
@@ -28,5 +28,4 @@ namespace Telegrator.Polling
DefaultUpdateReceiver updateReceiver = new DefaultUpdateReceiver(botClient, _receiverOptions); DefaultUpdateReceiver updateReceiver = new DefaultUpdateReceiver(botClient, _receiverOptions);
await updateReceiver.ReceiveAsync(_updateRouter, stoppingToken).ConfigureAwait(false); await updateReceiver.ReceiveAsync(_updateRouter, stoppingToken).ConfigureAwait(false);
} }
}
} }
@@ -1,11 +1,9 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
namespace Telegrator.Providers namespace Telegrator.Providers;
/// <inheritdoc/>
public class HostAwaitingProvider(IOptions<TelegratorOptions> options) : AwaitingProvider(options.Value)
{ {
/// <inheritdoc/>
public class HostAwaitingProvider(IOptions<TelegratorOptions> options, ILogger<HostAwaitingProvider> logger) : AwaitingProvider(options.Value)
{
private readonly ILogger<HostAwaitingProvider> _logger = logger;
}
} }
@@ -2,11 +2,11 @@
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Providers namespace Telegrator.Providers;
/// <inheritdoc/>
public class HostHandlersCollection(IServiceCollection hostServiceColletion, TelegratorOptions options) : HandlersCollection(options)
{ {
/// <inheritdoc/>
public class HostHandlersCollection(IServiceCollection hostServiceColletion, TelegratorOptions options) : HandlersCollection(options)
{
private readonly IServiceCollection Services = hostServiceColletion; private readonly IServiceCollection Services = hostServiceColletion;
/// <inheritdoc/> /// <inheritdoc/>
@@ -58,5 +58,4 @@ namespace Telegrator.Providers
return base.AddDescriptor(descriptor); return base.AddDescriptor(descriptor);
} }
}
} }
@@ -1,27 +1,23 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Providers namespace Telegrator.Providers;
/// <inheritdoc/>
public class HostHandlersProvider : HandlersProvider
{ {
/// <inheritdoc/>
public class HostHandlersProvider : HandlersProvider
{
private readonly IServiceProvider Services; private readonly IServiceProvider Services;
private readonly ILogger<HostHandlersProvider> Logger;
/// <inheritdoc/> /// <inheritdoc/>
public HostHandlersProvider( public HostHandlersProvider(
IHandlersCollection handlers, IHandlersCollection handlers,
IOptions<TelegratorOptions> options, IOptions<TelegratorOptions> options,
IServiceProvider serviceProvider, IServiceProvider serviceProvider) : base(handlers, options.Value)
ILogger<HostHandlersProvider> logger) : base(handlers, options.Value)
{ {
Services = serviceProvider; Services = serviceProvider;
Logger = logger;
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -41,5 +37,4 @@ namespace Telegrator.Providers
updateHandler.LifetimeToken.OnLifetimeEnded += _ => scope.Dispose(); updateHandler.LifetimeToken.OnLifetimeEnded += _ => scope.Dispose();
return updateHandler; return updateHandler;
} }
}
} }
@@ -15,7 +15,7 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<Title>Telegrator.Hosting</Title> <Title>Telegrator.Hosting</Title>
<Version>1.16.4</Version> <Version>1.16.5</Version>
<Authors>Rikitav Tim4ik</Authors> <Authors>Rikitav Tim4ik</Authors>
<Company>Rikitav Tim4ik</Company> <Company>Rikitav Tim4ik</Company>
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl> <RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
+15
View File
@@ -11,10 +11,12 @@ using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Core; using Telegrator.Core;
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
using Telegrator.Core.States;
using Telegrator.Hosting; using Telegrator.Hosting;
using Telegrator.Logging; using Telegrator.Logging;
using Telegrator.Polling; using Telegrator.Polling;
using Telegrator.Providers; using Telegrator.Providers;
using Telegrator.States;
namespace Telegrator; namespace Telegrator;
@@ -112,6 +114,18 @@ public static class HostBuilderExtensions
/// </summary> /// </summary>
public static class ServicesCollectionExtensions public static class ServicesCollectionExtensions
{ {
/// <summary>
/// Registers <see cref="IStateStorage"/> service
/// </summary>
/// <typeparam name="TStorage"></typeparam>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddStateStorage<TStorage>(this IServiceCollection services) where TStorage : IStateStorage
{
services.Replace(new ServiceDescriptor(typeof(IStateStorage), typeof(TStorage), ServiceLifetime.Singleton));
return services;
}
/// <summary> /// <summary>
/// Registers <see cref="TelegramBotHost"/> default services /// Registers <see cref="TelegramBotHost"/> default services
/// </summary> /// </summary>
@@ -124,6 +138,7 @@ public static class ServicesCollectionExtensions
services.AddSingleton<IHandlersProvider, HostHandlersProvider>(); services.AddSingleton<IHandlersProvider, HostHandlersProvider>();
services.AddSingleton<IUpdateRouter, HostUpdateRouter>(); services.AddSingleton<IUpdateRouter, HostUpdateRouter>();
services.AddSingleton<ITelegramBotInfo, HostedTelegramBotInfo>(); services.AddSingleton<ITelegramBotInfo, HostedTelegramBotInfo>();
services.AddSingleton<IStateStorage, DefaultStateStorage>();
return services; return services;
} }
@@ -4,14 +4,13 @@ using System.Threading.Tasks;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Handlers; using Telegrator.Handlers;
namespace Telegrator.Localized namespace Telegrator.Localized;
public static class LocalizedMessageHandlerExtensions
{ {
public static class LocalizedMessageHandlerExtensions
{
public static async Task<Message> ResponseLocalized(this ILocalizedHandler<Message> localizedHandler, string localizedReplyIdentifier, params IEnumerable<string> formatArgs) public static async Task<Message> ResponseLocalized(this ILocalizedHandler<Message> localizedHandler, string localizedReplyIdentifier, params IEnumerable<string> formatArgs)
{ {
LocalizedString localizedString = localizedHandler.LocalizationProvider[localizedReplyIdentifier, formatArgs]; LocalizedString localizedString = localizedHandler.LocalizationProvider[localizedReplyIdentifier, formatArgs];
return await localizedHandler.Container.Responce(localizedString.Value); return await localizedHandler.Container.Responce(localizedString.Value);
} }
}
} }
@@ -4,15 +4,15 @@ using Telegrator.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Abstract base attribute for filtering callback-based updates.
/// Supports various message types including regular messages, edited messages, channel posts, and business messages.
/// </summary>
/// <param name="filters">The filters to apply to messages</param>
public abstract class CallbackQueryAttribute(params IFilter<CallbackQuery>[] filters) : UpdateFilterAttribute<CallbackQuery>(filters)
{ {
/// <summary>
/// Abstract base attribute for filtering callback-based updates.
/// Supports various message types including regular messages, edited messages, channel posts, and business messages.
/// </summary>
/// <param name="filters">The filters to apply to messages</param>
public abstract class CallbackQueryAttribute(params IFilter<CallbackQuery>[] filters) : UpdateFilterAttribute<CallbackQuery>(filters)
{
/// <summary> /// <summary>
/// Gets the allowed update types that this filter can process. /// Gets the allowed update types that this filter can process.
/// </summary> /// </summary>
@@ -25,20 +25,19 @@ namespace Telegrator.Annotations
/// <returns>The message from the update, or null if not present</returns> /// <returns>The message from the update, or null if not present</returns>
public override CallbackQuery? GetFilterringTarget(Update update) public override CallbackQuery? GetFilterringTarget(Update update)
=> update.CallbackQuery; => update.CallbackQuery;
}
/// <summary>
/// Attribute for filtering <see cref="CallbackQuery"/>'s data
/// </summary>
/// <param name="data"></param>
public class CallbackDataAttribute(string data)
: CallbackQueryAttribute(new CallbackDataFilter(data))
{ }
/// <summary>
/// Attribute to check if <see cref="CallbackQuery"/> belongs to a specific message by its ID
/// </summary>
public class CallbackInlineIdAttribute(string inlineMessageId)
: CallbackQueryAttribute(new CallbackInlineIdFilter(inlineMessageId))
{ }
} }
/// <summary>
/// Attribute for filtering <see cref="CallbackQuery"/>'s data
/// </summary>
/// <param name="data"></param>
public class CallbackDataAttribute(string data)
: CallbackQueryAttribute(new CallbackDataFilter(data))
{ }
/// <summary>
/// Attribute to check if <see cref="CallbackQuery"/> belongs to a specific message by its ID
/// </summary>
public class CallbackInlineIdAttribute(string inlineMessageId)
: CallbackQueryAttribute(new CallbackInlineIdFilter(inlineMessageId))
{ }
@@ -3,14 +3,14 @@ using Telegram.Bot.Types.Enums;
using Telegrator.Filters; using Telegrator.Filters;
using Telegrator.Attributes; using Telegrator.Attributes;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Attribute for filtering messages based on command aliases.
/// Allows handlers to respond to multiple command variations using a single attribute.
/// </summary>
public class CommandAlliasAttribute : UpdateFilterAttribute<Message>
{ {
/// <summary>
/// Attribute for filtering messages based on command aliases.
/// Allows handlers to respond to multiple command variations using a single attribute.
/// </summary>
public class CommandAlliasAttribute : UpdateFilterAttribute<Message>
{
/// <summary> /// <summary>
/// Gets the allowed update types for this filter. /// Gets the allowed update types for this filter.
/// </summary> /// </summary>
@@ -56,5 +56,4 @@ namespace Telegrator.Annotations
/// <param name="update">The Telegram update.</param> /// <param name="update">The Telegram update.</param>
/// <returns>The message from the update, or null if not present.</returns> /// <returns>The message from the update, or null if not present.</returns>
public override Message? GetFilterringTarget(Update update) => update.Message; public override Message? GetFilterringTarget(Update update) => update.Message;
}
} }
@@ -1,63 +1,62 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
{
/// <summary> /// <summary>
/// Attribute for filtering messages where a command has arguments count >= <paramref name="count"/>. /// Attribute for filtering messages where a command has arguments count >= <paramref name="count"/>.
/// </summary> /// </summary>
/// <param name="count"></param> /// <param name="count"></param>
public class ArgumentCountAttribute(int count) public class ArgumentCountAttribute(int count)
: MessageFilterAttribute(new ArgumentCountFilter(count)) : MessageFilterAttribute(new ArgumentCountFilter(count))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where a command argument starts with the specified content. /// Attribute for filtering messages where a command argument starts with the specified content.
/// </summary> /// </summary>
/// <param name="content">The content that the command argument should start with.</param> /// <param name="content">The content that the command argument should start with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) public class ArgumentStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
: MessageFilterAttribute(new ArgumentStartsWithFilter(content, comparison, index)) : MessageFilterAttribute(new ArgumentStartsWithFilter(content, comparison, index))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where a command argument ends with the specified content. /// Attribute for filtering messages where a command argument ends with the specified content.
/// </summary> /// </summary>
/// <param name="content">The content that the command argument should end with.</param> /// <param name="content">The content that the command argument should end with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) public class ArgumentEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
: MessageFilterAttribute(new ArgumentEndsWithFilter(content, comparison, index)) : MessageFilterAttribute(new ArgumentEndsWithFilter(content, comparison, index))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where a command argument contains the specified content. /// Attribute for filtering messages where a command argument contains the specified content.
/// </summary> /// </summary>
/// <param name="content">The content that the command argument should contain.</param> /// <param name="content">The content that the command argument should contain.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) public class ArgumentContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
: MessageFilterAttribute(new ArgumentContainsFilter(content, comparison, index)) : MessageFilterAttribute(new ArgumentContainsFilter(content, comparison, index))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where a command argument equals the specified content. /// Attribute for filtering messages where a command argument equals the specified content.
/// </summary> /// </summary>
/// <param name="content">The content that the command argument should equal.</param> /// <param name="content">The content that the command argument should equal.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) public class ArgumentEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
: MessageFilterAttribute(new ArgumentEqualsFilter(content, comparison, index)) : MessageFilterAttribute(new ArgumentEqualsFilter(content, comparison, index))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where a command argument matches a regular expression pattern. /// Attribute for filtering messages where a command argument matches a regular expression pattern.
/// </summary> /// </summary>
/// <param name="pattern">The regular expression pattern to match against the command argument.</param> /// <param name="pattern">The regular expression pattern to match against the command argument.</param>
/// <param name="options">The regex options to use for the pattern matching.</param> /// <param name="options">The regex options to use for the pattern matching.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, int index = 0) public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, int index = 0)
: MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, index: index)) : MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, index: index))
{ } { }
}
@@ -1,12 +1,11 @@
namespace Telegrator.Annotations namespace Telegrator.Annotations;
{
/// <summary> /// <summary>
/// Attribute that prevents a class from being automatically collected by the handler collection system. /// Attribute that prevents a class from being automatically collected by the handler collection system.
/// When applied to a class, it will be excluded from domain-wide handler collection operations. /// When applied to a class, it will be excluded from domain-wide handler collection operations.
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class DontCollectAttribute : Attribute public class DontCollectAttribute : Attribute
{ {
}
} }
@@ -4,15 +4,15 @@ using Telegrator.Filters;
using Telegrator.Attributes; using Telegrator.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Abstract base attribute for filtering updates based on environment conditions.
/// Can process all types of updates and provides environment-specific filtering logic.
/// </summary>
/// <param name="filters">The environment filters to apply</param>
public abstract class EnvironmentFilterAttribute(params IFilter<Update>[] filters) : UpdateFilterAttribute<Update>(filters)
{ {
/// <summary>
/// Abstract base attribute for filtering updates based on environment conditions.
/// Can process all types of updates and provides environment-specific filtering logic.
/// </summary>
/// <param name="filters">The environment filters to apply</param>
public abstract class EnvironmentFilterAttribute(params IFilter<Update>[] filters) : UpdateFilterAttribute<Update>(filters)
{
/// <summary> /// <summary>
/// Gets the allowed update types that this filter can process. /// Gets the allowed update types that this filter can process.
/// Environment filters can process all update types. /// Environment filters can process all update types.
@@ -27,29 +27,29 @@ namespace Telegrator.Annotations
/// <returns>The update object itself</returns> /// <returns>The update object itself</returns>
public override Update? GetFilterringTarget(Update update) public override Update? GetFilterringTarget(Update update)
=> update; => update;
} }
/// <summary> /// <summary>
/// Attribute for filtering updates that occur in debug environment. /// Attribute for filtering updates that occur in debug environment.
/// Only allows updates when the application is running in debug mode. /// Only allows updates when the application is running in debug mode.
/// </summary> /// </summary>
public class IsDebugEnvironmentAttribute() public class IsDebugEnvironmentAttribute()
: EnvironmentFilterAttribute(new IsDebugEnvironmentFilter()) : EnvironmentFilterAttribute(new IsDebugEnvironmentFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering updates that occur in release environment. /// Attribute for filtering updates that occur in release environment.
/// Only allows updates when the application is running in release mode. /// Only allows updates when the application is running in release mode.
/// </summary> /// </summary>
public class IsReleaseEnvironmentAttribute() public class IsReleaseEnvironmentAttribute()
: EnvironmentFilterAttribute(new IsReleaseEnvironmentFilter()) : EnvironmentFilterAttribute(new IsReleaseEnvironmentFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering updates based on environment variable values. /// Attribute for filtering updates based on environment variable values.
/// </summary> /// </summary>
public class EnvironmentVariableAttribute : EnvironmentFilterAttribute public class EnvironmentVariableAttribute : EnvironmentFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter based on an environment variable with a specific value and comparison method. /// Initializes the attribute to filter based on an environment variable with a specific value and comparison method.
/// </summary> /// </summary>
@@ -81,5 +81,4 @@ namespace Telegrator.Annotations
/// <param name="comparison">The string comparison method</param> /// <param name="comparison">The string comparison method</param>
public EnvironmentVariableAttribute(string variable, StringComparison comparison) public EnvironmentVariableAttribute(string variable, StringComparison comparison)
: base(new EnvironmentVariableFilter(variable, comparison)) { } : base(new EnvironmentVariableFilter(variable, comparison)) { }
}
} }
@@ -1,14 +1,14 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Attribute for filtering messages that contain mentions.
/// Allows handlers to respond only to messages that mention the bot or specific users.
/// </summary>
public class MentionedAttribute : MessageFilterAttribute
{ {
/// <summary>
/// Attribute for filtering messages that contain mentions.
/// Allows handlers to respond only to messages that mention the bot or specific users.
/// </summary>
public class MentionedAttribute : MessageFilterAttribute
{
/// <summary> /// <summary>
/// Initializes a new instance of the MentionedAttribute that matches any mention. /// Initializes a new instance of the MentionedAttribute that matches any mention.
/// </summary> /// </summary>
@@ -36,5 +36,4 @@ namespace Telegrator.Annotations
/// <param name="offset">The offset position where the mention should occur.</param> /// <param name="offset">The offset position where the mention should occur.</param>
public MentionedAttribute(string mention, int offset) public MentionedAttribute(string mention, int offset)
: base(new MessageHasEntityFilter(MessageEntityType.Mention, offset, null), new MentionedFilter(mention)) { } : base(new MessageHasEntityFilter(MessageEntityType.Mention, offset, null), new MentionedFilter(mention)) { }
}
} }
@@ -1,28 +1,28 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
{
/// <summary> /// <summary>
/// Attribute for filtering messages sent in forum chats. /// Attribute for filtering messages sent in forum chats.
/// </summary> /// </summary>
public class ChatIsForumAttribute() public class ChatIsForumAttribute()
: MessageFilterAttribute(new MessageChatIsForumFilter()) : MessageFilterAttribute(new MessageChatIsForumFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages sent in a specific chat by ID. /// Attribute for filtering messages sent in a specific chat by ID.
/// </summary> /// </summary>
/// <param name="id">The chat ID to match</param> /// <param name="id">The chat ID to match</param>
public class ChatIdAttribute(long id) public class ChatIdAttribute(long id)
: MessageFilterAttribute(new MessageChatIdFilter(id)) : MessageFilterAttribute(new MessageChatIdFilter(id))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages sent in chats of a specific type. /// Attribute for filtering messages sent in chats of a specific type.
/// </summary> /// </summary>
public class ChatTypeAttribute : MessageFilterAttribute public class ChatTypeAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initialize new instance of <see cref="ChatTypeAttribute"/> to filter messages from chat from specific chats /// Initialize new instance of <see cref="ChatTypeAttribute"/> to filter messages from chat from specific chats
/// </summary> /// </summary>
@@ -36,13 +36,13 @@ namespace Telegrator.Annotations
/// <param name="flags"></param> /// <param name="flags"></param>
public ChatTypeAttribute(ChatTypeFlags flags) public ChatTypeAttribute(ChatTypeFlags flags)
: base(new MessageChatTypeFilter(flags)) { } : base(new MessageChatTypeFilter(flags)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages based on the chat title. /// Attribute for filtering messages based on the chat title.
/// </summary> /// </summary>
public class ChatTitleAttribute : MessageFilterAttribute public class ChatTitleAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter messages from chats with a specific title and comparison method. /// Initializes the attribute to filter messages from chats with a specific title and comparison method.
/// </summary> /// </summary>
@@ -57,13 +57,13 @@ namespace Telegrator.Annotations
/// <param name="title">The chat title to match</param> /// <param name="title">The chat title to match</param>
public ChatTitleAttribute(string? title) public ChatTitleAttribute(string? title)
: base(new MessageChatTitleFilter(title)) { } : base(new MessageChatTitleFilter(title)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages based on the chat username. /// Attribute for filtering messages based on the chat username.
/// </summary> /// </summary>
public class ChatUsernameAttribute : MessageFilterAttribute public class ChatUsernameAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter messages from chats with a specific username and comparison method. /// Initializes the attribute to filter messages from chats with a specific username and comparison method.
/// </summary> /// </summary>
@@ -78,13 +78,13 @@ namespace Telegrator.Annotations
/// <param name="userName">The chat username to match</param> /// <param name="userName">The chat username to match</param>
public ChatUsernameAttribute(string? userName) public ChatUsernameAttribute(string? userName)
: base(new MessageChatUsernameFilter(userName, StringComparison.InvariantCulture)) { } : base(new MessageChatUsernameFilter(userName, StringComparison.InvariantCulture)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages based on the chat name (first name and optionally last name). /// Attribute for filtering messages based on the chat name (first name and optionally last name).
/// </summary> /// </summary>
public class ChatNameAttribute : MessageFilterAttribute public class ChatNameAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter messages from chats with specific first and last names. /// Initializes the attribute to filter messages from chats with specific first and last names.
/// </summary> /// </summary>
@@ -101,5 +101,4 @@ namespace Telegrator.Annotations
/// <param name="lastName">The last name to match (optional)</param> /// <param name="lastName">The last name to match (optional)</param>
public ChatNameAttribute(string? firstName, string? lastName) public ChatNameAttribute(string? firstName, string? lastName)
: base(new MessageChatNameFilter(firstName, lastName)) { } : base(new MessageChatNameFilter(firstName, lastName)) { }
}
} }
@@ -5,15 +5,15 @@ using Telegrator.Filters;
using Telegrator.Attributes; using Telegrator.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Abstract base attribute for filtering message-based updates.
/// Supports various message types including regular messages, edited messages, channel posts, and business messages.
/// </summary>
/// <param name="filters">The filters to apply to messages</param>
public abstract class MessageFilterAttribute(params IFilter<Message>[] filters) : UpdateFilterAttribute<Message>(filters)
{ {
/// <summary>
/// Abstract base attribute for filtering message-based updates.
/// Supports various message types including regular messages, edited messages, channel posts, and business messages.
/// </summary>
/// <param name="filters">The filters to apply to messages</param>
public abstract class MessageFilterAttribute(params IFilter<Message>[] filters) : UpdateFilterAttribute<Message>(filters)
{
/// <summary> /// <summary>
/// Gets the allowed update types that this filter can process. /// Gets the allowed update types that this filter can process.
/// </summary> /// </summary>
@@ -45,13 +45,13 @@ namespace Telegrator.Annotations
_ => null _ => null
}; };
} }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages based on regular expression patterns. /// Attribute for filtering messages based on regular expression patterns.
/// </summary> /// </summary>
public class MessageRegexAttribute : MessageFilterAttribute public class MessageRegexAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute with a regex pattern and options. /// Initializes the attribute with a regex pattern and options.
/// </summary> /// </summary>
@@ -66,13 +66,13 @@ namespace Telegrator.Annotations
/// <param name="regex">The precompiled regular expression</param> /// <param name="regex">The precompiled regular expression</param>
public MessageRegexAttribute(Regex regex) public MessageRegexAttribute(Regex regex)
: base(new MessageRegexFilter(regex)) { } : base(new MessageRegexFilter(regex)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages that contain dice throws with specific values. /// Attribute for filtering messages that contain dice throws with specific values.
/// </summary> /// </summary>
public class DiceThrowedAttribute : MessageFilterAttribute public class DiceThrowedAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter dice throws with a specific value. /// Initializes the attribute to filter dice throws with a specific value.
/// </summary> /// </summary>
@@ -87,41 +87,41 @@ namespace Telegrator.Annotations
/// <param name="value">The dice value to match</param> /// <param name="value">The dice value to match</param>
public DiceThrowedAttribute(DiceType diceType, int value) public DiceThrowedAttribute(DiceType diceType, int value)
: base(new DiceThrowedFilter(diceType, value)) { } : base(new DiceThrowedFilter(diceType, value)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages that are automatically forwarded. /// Attribute for filtering messages that are automatically forwarded.
/// </summary> /// </summary>
public class IsAutomaticFormwardMessageAttribute() public class IsAutomaticFormwardMessageAttribute()
: MessageFilterAttribute(new IsAutomaticFormwardMessageFilter()) : MessageFilterAttribute(new IsAutomaticFormwardMessageFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages sent while the user was offline. /// Attribute for filtering messages sent while the user was offline.
/// </summary> /// </summary>
public class IsFromOfflineMessageAttribute() public class IsFromOfflineMessageAttribute()
: MessageFilterAttribute(new IsFromOfflineMessageFilter()) : MessageFilterAttribute(new IsFromOfflineMessageFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering service messages (e.g., user joined, left, etc.). /// Attribute for filtering service messages (e.g., user joined, left, etc.).
/// </summary> /// </summary>
public class IsServiceMessageMessageAttribute() public class IsServiceMessageMessageAttribute()
: MessageFilterAttribute(new IsServiceMessageMessageFilter()) : MessageFilterAttribute(new IsServiceMessageMessageFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering topic messages in forum chats. /// Attribute for filtering topic messages in forum chats.
/// </summary> /// </summary>
public class IsTopicMessageMessageAttribute() public class IsTopicMessageMessageAttribute()
: MessageFilterAttribute(new IsServiceMessageMessageFilter()) : MessageFilterAttribute(new IsServiceMessageMessageFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages based on their entities (mentions, links, etc.). /// Attribute for filtering messages based on their entities (mentions, links, etc.).
/// </summary> /// </summary>
public class MessageHasEntityAttribute : MessageFilterAttribute public class MessageHasEntityAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter messages with a specific entity type. /// Initializes the attribute to filter messages with a specific entity type.
/// </summary> /// </summary>
@@ -157,5 +157,4 @@ namespace Telegrator.Annotations
/// <param name="stringComparison">The string comparison method</param> /// <param name="stringComparison">The string comparison method</param>
public MessageHasEntityAttribute(MessageEntityType type, int offset, int? length, string content, StringComparison stringComparison = StringComparison.CurrentCulture) public MessageHasEntityAttribute(MessageEntityType type, int offset, int? length, string content, StringComparison stringComparison = StringComparison.CurrentCulture)
: base(new MessageHasEntityFilter(type, offset, length, content, stringComparison)) { } : base(new MessageHasEntityFilter(type, offset, length, content, stringComparison)) { }
}
} }
@@ -1,27 +1,26 @@
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
{
/// <summary> /// <summary>
/// Attribute for filtering messages with reply to messages of this bot. /// Attribute for filtering messages with reply to messages of this bot.
/// </summary> /// </summary>
public class MeRepliedAttribute() public class MeRepliedAttribute()
: MessageFilterAttribute(new MeRepliedFilter()) : MessageFilterAttribute(new MeRepliedFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for checking message's reply chain. /// Attribute for checking message's reply chain.
/// </summary> /// </summary>
public class HasReplyAttribute(int replyDepth = 1) public class HasReplyAttribute(int replyDepth = 1)
: MessageFilterAttribute(new MessageHasReplyFilter(replyDepth)) : MessageFilterAttribute(new MessageHasReplyFilter(replyDepth))
{ } { }
/// <summary> /// <summary>
/// Helper filter class for filters that operate on replied messages. /// Helper filter class for filters that operate on replied messages.
/// Provides functionality to traverse reply chains and access replied message content. /// Provides functionality to traverse reply chains and access replied message content.
/// </summary> /// </summary>
/// <param name="replyDepth"></param> /// <param name="replyDepth"></param>
public class FromReplyChainAttribute(int replyDepth = 1) public class FromReplyChainAttribute(int replyDepth = 1)
: MessageFilterAttribute(new FromReplyChainFilter(replyDepth)) : MessageFilterAttribute(new FromReplyChainFilter(replyDepth))
{ } { }
}
@@ -1,12 +1,12 @@
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Attribute for filtering messages based on the sender's username.
/// </summary>
public class FromUsernameAttribute : MessageFilterAttribute
{ {
/// <summary>
/// Attribute for filtering messages based on the sender's username.
/// </summary>
public class FromUsernameAttribute : MessageFilterAttribute
{
/// <summary> /// <summary>
/// Initializes the attribute to filter messages from a specific username. /// Initializes the attribute to filter messages from a specific username.
/// </summary> /// </summary>
@@ -21,13 +21,13 @@ namespace Telegrator.Annotations
/// <param name="comparison">The string comparison method</param> /// <param name="comparison">The string comparison method</param>
public FromUsernameAttribute(string username, StringComparison comparison) public FromUsernameAttribute(string username, StringComparison comparison)
: base(new FromUsernameFilter(username, comparison)) { } : base(new FromUsernameFilter(username, comparison)) { }
} }
/// <summary> /// <summary>
/// Attribute for filtering messages based on the sender's name (first name and optionally last name). /// Attribute for filtering messages based on the sender's name (first name and optionally last name).
/// </summary> /// </summary>
public class FromUserAttribute : MessageFilterAttribute public class FromUserAttribute : MessageFilterAttribute
{ {
/// <summary> /// <summary>
/// Initializes the attribute to filter messages from a user with specific first and last names. /// Initializes the attribute to filter messages from a user with specific first and last names.
/// </summary> /// </summary>
@@ -59,34 +59,33 @@ namespace Telegrator.Annotations
/// <param name="comparison">The string comparison method</param> /// <param name="comparison">The string comparison method</param>
public FromUserAttribute(string firstName, StringComparison comparison) public FromUserAttribute(string firstName, StringComparison comparison)
: base(new FromUserFilter(firstName, null, comparison)) { } : base(new FromUserFilter(firstName, null, comparison)) { }
}
/// <summary>
/// Attribute for filtering messages from a specific user ID.
/// </summary>
/// <param name="userId">The user ID to match</param>
public class FromUserIdAttribute(long userId)
: MessageFilterAttribute(new FromUserIdFilter(userId))
{ }
/// <summary>
/// Attribute for filtering messages sent by not bots (users).
/// </summary>
public class NotFromBotAttribute()
: MessageFilterAttribute(new FromBotFilter().Not())
{ }
/// <summary>
/// Attribute for filtering messages sent by bots.
/// </summary>
public class FromBotAttribute()
: MessageFilterAttribute(new FromBotFilter())
{ }
/// <summary>
/// Attribute for filtering messages sent by premium users.
/// </summary>
public class FromPremiumUserAttribute()
: MessageFilterAttribute(new FromPremiumUserFilter())
{ }
} }
/// <summary>
/// Attribute for filtering messages from a specific user ID.
/// </summary>
/// <param name="userId">The user ID to match</param>
public class FromUserIdAttribute(long userId)
: MessageFilterAttribute(new FromUserIdFilter(userId))
{ }
/// <summary>
/// Attribute for filtering messages sent by not bots (users).
/// </summary>
public class NotFromBotAttribute()
: MessageFilterAttribute(new FromBotFilter().Not())
{ }
/// <summary>
/// Attribute for filtering messages sent by bots.
/// </summary>
public class FromBotAttribute()
: MessageFilterAttribute(new FromBotFilter())
{ }
/// <summary>
/// Attribute for filtering messages sent by premium users.
/// </summary>
public class FromPremiumUserAttribute()
: MessageFilterAttribute(new FromPremiumUserFilter())
{ }
@@ -1,58 +1,57 @@
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
{
/// <summary> /// <summary>
/// Attribute for filtering messages where the text starts with the specified content. /// Attribute for filtering messages where the text starts with the specified content.
/// </summary> /// </summary>
/// <param name="content">The string that the message text should start with</param> /// <param name="content">The string that the message text should start with</param>
/// <param name="comparison">The string comparison type</param> /// <param name="comparison">The string comparison type</param>
public class TextStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture) public class TextStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture)
: MessageFilterAttribute(new TextStartsWithFilter(content, comparison)) : MessageFilterAttribute(new TextStartsWithFilter(content, comparison))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where the text ends with the specified content. /// Attribute for filtering messages where the text ends with the specified content.
/// </summary> /// </summary>
/// <param name="content">The string that the message text should end with</param> /// <param name="content">The string that the message text should end with</param>
/// <param name="comparison">The string comparison type</param> /// <param name="comparison">The string comparison type</param>
public class TextEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture) public class TextEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture)
: MessageFilterAttribute(new TextEndsWithFilter(content, comparison)) : MessageFilterAttribute(new TextEndsWithFilter(content, comparison))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where the text contains the specified content. /// Attribute for filtering messages where the text contains the specified content.
/// </summary> /// </summary>
/// <param name="content">The string that the message text should contain</param> /// <param name="content">The string that the message text should contain</param>
/// <param name="comparison">The string comparison type</param> /// <param name="comparison">The string comparison type</param>
public class TextContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture) public class TextContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture)
: MessageFilterAttribute(new TextContainsFilter(content, comparison)) : MessageFilterAttribute(new TextContainsFilter(content, comparison))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where the text equals the specified content. /// Attribute for filtering messages where the text equals the specified content.
/// </summary> /// </summary>
/// <param name="content">The string that the message text should equal</param> /// <param name="content">The string that the message text should equal</param>
/// <param name="comparison">The string comparison type</param> /// <param name="comparison">The string comparison type</param>
public class TextEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture) public class TextEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture)
: MessageFilterAttribute(new TextEqualsFilter(content, comparison)) : MessageFilterAttribute(new TextEqualsFilter(content, comparison))
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages that contain any non-empty text. /// Attribute for filtering messages that contain any non-empty text.
/// </summary> /// </summary>
public class HasTextAttribute() public class HasTextAttribute()
: MessageFilterAttribute(new TextNotNullOrEmptyFilter()) : MessageFilterAttribute(new TextNotNullOrEmptyFilter())
{ } { }
/// <summary> /// <summary>
/// Attribute for filtering messages where the text contains a 'word'. /// Attribute for filtering messages where the text contains a 'word'.
/// 'Word' must be a separate member of the text, and not have any alphabetic characters next to it. /// 'Word' must be a separate member of the text, and not have any alphabetic characters next to it.
/// </summary> /// </summary>
/// <param name="word"></param> /// <param name="word"></param>
/// <param name="comparison"></param> /// <param name="comparison"></param>
/// <param name="startIndex"></param> /// <param name="startIndex"></param>
public class TextContainsWordAttribute(string word, StringComparison comparison = StringComparison.InvariantCulture, int startIndex = 0) public class TextContainsWordAttribute(string word, StringComparison comparison = StringComparison.InvariantCulture, int startIndex = 0)
: MessageFilterAttribute(new TextContainsWordFilter(word, comparison, startIndex)) : MessageFilterAttribute(new TextContainsWordFilter(word, comparison, startIndex))
{ } { }
}
@@ -1,15 +1,15 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Attribute that says if this handler can await some of await types, that is not listed by its handler base.
/// Used for automatic collecting allowed to receiving <see cref="UpdateType"/>'s.
/// If you don't use it, you won't be able to await the updates inside handler.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MightAwaitAttribute : Attribute
{ {
/// <summary>
/// Attribute that says if this handler can await some of await types, that is not listed by its handler base.
/// Used for automatic collecting allowed to receiving <see cref="UpdateType"/>'s.
/// If you don't use it, you won't be able to await the updates inside handler.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MightAwaitAttribute : Attribute
{
private readonly UpdateType[] _updateTypes; private readonly UpdateType[] _updateTypes;
/// <summary> /// <summary>
@@ -23,5 +23,4 @@ namespace Telegrator.Annotations
/// <param name="updateTypes"></param> /// <param name="updateTypes"></param>
public MightAwaitAttribute(params UpdateType[] updateTypes) public MightAwaitAttribute(params UpdateType[] updateTypes)
=> _updateTypes = updateTypes; => _updateTypes = updateTypes;
}
} }
@@ -2,14 +2,14 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Annotations namespace Telegrator.Annotations;
/// <summary>
/// Attribute for filtering message with command "start" in bot's private chats.
/// Allows handlers to respond to "welcome" bot commands.
/// </summary>
public class WelcomeAttribute : MessageFilterAttribute
{ {
/// <summary>
/// Attribute for filtering message with command "start" in bot's private chats.
/// Allows handlers to respond to "welcome" bot commands.
/// </summary>
public class WelcomeAttribute : MessageFilterAttribute
{
/// <summary> /// <summary>
/// Creates new instance of <see cref="WelcomeAttribute"/> /// Creates new instance of <see cref="WelcomeAttribute"/>
/// </summary> /// </summary>
@@ -19,5 +19,4 @@ namespace Telegrator.Annotations
new CommandAlliasFilter("start"), new CommandAlliasFilter("start"),
Filter<Message>.If(ctx => !onlyFirst || ctx.Input.Id == 0)) Filter<Message>.If(ctx => !onlyFirst || ctx.Input.Id == 0))
{ } { }
}
} }
@@ -1,16 +1,15 @@
namespace Telegrator.Aspects namespace Telegrator.Aspects;
/// <summary>
/// Attribute that specifies a post-execution processor to be executed after the handler.
/// The processor type must implement <see cref="IPostProcessor"/> interface.
/// </summary>
/// <typeparam name="T">The type of the post-processor that implements <see cref="IPostProcessor"/>.</typeparam>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AfterExecutionAttribute<T> : Attribute where T : IPostProcessor
{ {
/// <summary>
/// Attribute that specifies a post-execution processor to be executed after the handler.
/// The processor type must implement <see cref="IPostProcessor"/> interface.
/// </summary>
/// <typeparam name="T">The type of the post-processor that implements <see cref="IPostProcessor"/>.</typeparam>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AfterExecutionAttribute<T> : Attribute where T : IPostProcessor
{
/// <summary> /// <summary>
/// Gets the type of the post-processor. /// Gets the type of the post-processor.
/// </summary> /// </summary>
public Type ProcessorType => typeof(T); public Type ProcessorType => typeof(T);
}
} }
@@ -1,16 +1,15 @@
namespace Telegrator.Aspects namespace Telegrator.Aspects;
/// <summary>
/// Attribute that specifies a pre-execution processor to be executed before the handler.
/// The processor type must implement <see cref="IPreProcessor"/> interface.
/// </summary>
/// <typeparam name="T">The type of the pre-processor that implements <see cref="IPreProcessor"/>.</typeparam>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class BeforeExecutionAttribute<T> : Attribute where T : IPreProcessor
{ {
/// <summary>
/// Attribute that specifies a pre-execution processor to be executed before the handler.
/// The processor type must implement <see cref="IPreProcessor"/> interface.
/// </summary>
/// <typeparam name="T">The type of the pre-processor that implements <see cref="IPreProcessor"/>.</typeparam>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class BeforeExecutionAttribute<T> : Attribute where T : IPreProcessor
{
/// <summary> /// <summary>
/// Gets the type of the pre-processor. /// Gets the type of the pre-processor.
/// </summary> /// </summary>
public Type ProcessorType => typeof(T); public Type ProcessorType => typeof(T);
}
} }
+7 -8
View File
@@ -1,13 +1,13 @@
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Aspects namespace Telegrator.Aspects;
/// <summary>
/// Interface for post-execution processors that are executed after handler execution.
/// Implement this interface to add cross-cutting concerns like logging, cleanup, or metrics collection.
/// </summary>
public interface IPostProcessor
{ {
/// <summary>
/// Interface for post-execution processors that are executed after handler execution.
/// Implement this interface to add cross-cutting concerns like logging, cleanup, or metrics collection.
/// </summary>
public interface IPostProcessor
{
/// <summary> /// <summary>
/// Executes after the handler's main execution logic. /// Executes after the handler's main execution logic.
/// </summary> /// </summary>
@@ -15,5 +15,4 @@ namespace Telegrator.Aspects
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns>A <see cref="Result"/> indicating the final execution result.</returns> /// <returns>A <see cref="Result"/> indicating the final execution result.</returns>
public Task<Result> AfterExecution(IHandlerContainer container, CancellationToken cancellationToken); public Task<Result> AfterExecution(IHandlerContainer container, CancellationToken cancellationToken);
}
} }
+7 -8
View File
@@ -1,13 +1,13 @@
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Aspects namespace Telegrator.Aspects;
/// <summary>
/// Interface for pre-execution processors that are executed before handler execution.
/// Implement this interface to add cross-cutting concerns like validation, logging, or authorization.
/// </summary>
public interface IPreProcessor
{ {
/// <summary>
/// Interface for pre-execution processors that are executed before handler execution.
/// Implement this interface to add cross-cutting concerns like validation, logging, or authorization.
/// </summary>
public interface IPreProcessor
{
/// <summary> /// <summary>
/// Executes before the handler's main execution logic. /// Executes before the handler's main execution logic.
/// </summary> /// </summary>
@@ -15,5 +15,4 @@ namespace Telegrator.Aspects
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns>A <see cref="Result"/> indicating whether execution should continue or be stopped.</returns> /// <returns>A <see cref="Result"/> indicating whether execution should continue or be stopped.</returns>
public Task<Result> BeforeExecution(IHandlerContainer container, CancellationToken cancellationToken = default); public Task<Result> BeforeExecution(IHandlerContainer container, CancellationToken cancellationToken = default);
}
} }
@@ -3,14 +3,14 @@ using Telegram.Bot.Types.Enums;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Attributes namespace Telegrator.Attributes;
/// <summary>
/// Reactive way to implement a new <see cref="UpdateFilterAttribute{T}"/> of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class FilterAnnotation<T> : UpdateFilterAttribute<T>, IFilter<T>, INamedFilter where T : class
{ {
/// <summary>
/// Reactive way to implement a new <see cref="UpdateFilterAttribute{T}"/> of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class FilterAnnotation<T> : UpdateFilterAttribute<T>, IFilter<T>, INamedFilter where T : class
{
/// <inheritdoc/> /// <inheritdoc/>
public virtual bool IsCollectible { get; } = false; public virtual bool IsCollectible { get; } = false;
@@ -35,5 +35,4 @@ namespace Telegrator.Attributes
/// <inheritdoc/> /// <inheritdoc/>
public abstract bool CanPass(FilterExecutionContext<T> context); public abstract bool CanPass(FilterExecutionContext<T> context);
}
} }
+8 -9
View File
@@ -1,12 +1,12 @@
namespace Telegrator.Attributes namespace Telegrator.Attributes;
/// <summary>
/// Enumeration of filter modifiers that can be applied to update filters.
/// Defines how filters should be combined and applied in filter chains.
/// </summary>
[Flags]
public enum FilterModifier
{ {
/// <summary>
/// Enumeration of filter modifiers that can be applied to update filters.
/// Defines how filters should be combined and applied in filter chains.
/// </summary>
[Flags]
public enum FilterModifier
{
/// <summary> /// <summary>
/// No modifier applied. Filter is applied as-is. /// No modifier applied. Filter is applied as-is.
/// </summary> /// </summary>
@@ -21,5 +21,4 @@
/// NOT modifier. The inverse of this filter should match. /// NOT modifier. The inverse of this filter should match.
/// </summary> /// </summary>
Not = 4, Not = 4,
}
} }
@@ -3,15 +3,15 @@ using Telegrator.Core.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Attributes namespace Telegrator.Attributes;
/// <summary>
/// Abstract base attribute for defining update filters for a specific type of update target.
/// Provides logic for filter composition, modifier processing, and target extraction.
/// </summary>
/// <typeparam name="T">The type of the update target to filter (e.g., Message, Update).</typeparam>
public abstract class UpdateFilterAttribute<T> : UpdateFilterAttributeBase where T : class
{ {
/// <summary>
/// Abstract base attribute for defining update filters for a specific type of update target.
/// Provides logic for filter composition, modifier processing, and target extraction.
/// </summary>
/// <typeparam name="T">The type of the update target to filter (e.g., Message, Update).</typeparam>
public abstract class UpdateFilterAttribute<T> : UpdateFilterAttributeBase where T : class
{
/// <summary> /// <summary>
/// Gets the compiled anonymous filter for this attribute. /// Gets the compiled anonymous filter for this attribute.
/// </summary> /// </summary>
@@ -81,5 +81,4 @@ namespace Telegrator.Attributes
/// <param name="update">The Telegram update</param> /// <param name="update">The Telegram update</param>
/// <returns>The target object to filter, or null if not applicable</returns> /// <returns>The target object to filter, or null if not applicable</returns>
public abstract T? GetFilterringTarget(Update update); public abstract T? GetFilterringTarget(Update update);
}
} }
@@ -2,15 +2,15 @@
using Telegrator.Core.Attributes; using Telegrator.Core.Attributes;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Attributes namespace Telegrator.Attributes;
/// <summary>
/// Abstract base attribute for marking update handler classes.
/// Provides a type-safe way to associate handler types with specific update types and importance settings.
/// </summary>
/// <typeparam name="T">The type of the update handler that this attribute is applied to.</typeparam>
public abstract class UpdateHandlerAttribute<T> : UpdateHandlerAttributeBase where T : UpdateHandlerBase
{ {
/// <summary>
/// Abstract base attribute for marking update handler classes.
/// Provides a type-safe way to associate handler types with specific update types and importance settings.
/// </summary>
/// <typeparam name="T">The type of the update handler that this attribute is applied to.</typeparam>
public abstract class UpdateHandlerAttribute<T> : UpdateHandlerAttributeBase where T : UpdateHandlerBase
{
/// <summary> /// <summary>
/// Initializes new instance of <see cref="UpdateHandlerAttribute{T}"/> /// Initializes new instance of <see cref="UpdateHandlerAttribute{T}"/>
/// </summary> /// </summary>
@@ -42,5 +42,4 @@ namespace Telegrator.Attributes
/// <param name="importance">The importance level for this handler</param> /// <param name="importance">The importance level for this handler</param>
protected UpdateHandlerAttribute(Type[] types, UpdateType updateType, int importance) protected UpdateHandlerAttribute(Type[] types, UpdateType updateType, int importance)
: base([.. types, typeof(T)], updateType, importance) { } : base([.. types, typeof(T)], updateType, importance) { }
}
} }
@@ -5,14 +5,14 @@ using Telegrator.Core.Filters;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Core.Attributes namespace Telegrator.Core.Attributes;
/// <summary>
/// Defines the <see cref="IFilter{T}"/> to <see cref="Update"/> validation for entry into execution of the <see cref="UpdateHandlerBase"/>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class UpdateFilterAttributeBase : Attribute
{ {
/// <summary>
/// Defines the <see cref="IFilter{T}"/> to <see cref="Update"/> validation for entry into execution of the <see cref="UpdateHandlerBase"/>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class UpdateFilterAttributeBase : Attribute
{
/// <summary> /// <summary>
/// Gets the <see cref="UpdateType"/>'s that <see cref="UpdateHandlerBase"/> processing /// Gets the <see cref="UpdateType"/>'s that <see cref="UpdateHandlerBase"/> processing
/// </summary> /// </summary>
@@ -43,5 +43,4 @@ namespace Telegrator.Core.Attributes
/// <param name="previous"></param> /// <param name="previous"></param>
/// <returns></returns> /// <returns></returns>
public abstract bool ProcessModifiers(UpdateFilterAttributeBase? previous); public abstract bool ProcessModifiers(UpdateFilterAttributeBase? previous);
}
} }
@@ -4,14 +4,14 @@ using Telegrator.Core.Descriptors;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Core.Attributes namespace Telegrator.Core.Attributes;
/// <summary>
/// Defines the <see cref="UpdateType"/>'s and validator (<see cref="IFilter{T}"/>) of the <see cref="Update"/> that <see cref="UpdateHandlerBase"/> will process
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class UpdateHandlerAttributeBase : Attribute, IFilter<Update>
{ {
/// <summary>
/// Defines the <see cref="UpdateType"/>'s and validator (<see cref="IFilter{T}"/>) of the <see cref="Update"/> that <see cref="UpdateHandlerBase"/> will process
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class UpdateHandlerAttributeBase : Attribute, IFilter<Update>
{
/// <inheritdoc/> /// <inheritdoc/>
public bool IsCollectible => GetType().HasPublicProperties(); public bool IsCollectible => GetType().HasPublicProperties();
@@ -78,5 +78,4 @@ namespace Telegrator.Core.Attributes
/// <param name="context">The filter execution context containing the update to validate.</param> /// <param name="context">The filter execution context containing the update to validate.</param>
/// <returns>True if the update passes validation; otherwise, false.</returns> /// <returns>True if the update passes validation; otherwise, false.</returns>
public abstract bool CanPass(FilterExecutionContext<Update> context); public abstract bool CanPass(FilterExecutionContext<Update> context);
}
} }
@@ -7,14 +7,14 @@ using Telegrator.Core.Handlers;
using Telegrator.Handlers; using Telegrator.Handlers;
using Telegrator.Handlers.Building; using Telegrator.Handlers.Building;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Descriptor for creating handlers from methods
/// </summary>
/// <typeparam name="TUpdate"></typeparam>
public class MethodHandlerDescriptor<TUpdate> : HandlerDescriptor where TUpdate : class
{ {
/// <summary>
/// Descriptor for creating handlers from methods
/// </summary>
/// <typeparam name="TUpdate"></typeparam>
public class MethodHandlerDescriptor<TUpdate> : HandlerDescriptor where TUpdate : class
{
private readonly MethodInfo Method; private readonly MethodInfo Method;
/// <summary> /// <summary>
@@ -66,5 +66,4 @@ namespace Telegrator.Core.Descriptors
} }
} }
} }
}
} }
@@ -4,13 +4,13 @@ using Telegrator.Core.Filters;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Contains information about a described handler, including its context, client, and execution logic.
/// </summary>
public class DescribedHandlerDescriptor
{ {
/// <summary>
/// Contains information about a described handler, including its context, client, and execution logic.
/// </summary>
public class DescribedHandlerDescriptor
{
private readonly ManualResetEventSlim ResetEvent = new ManualResetEventSlim(false); private readonly ManualResetEventSlim ResetEvent = new ManualResetEventSlim(false);
/// <summary> /// <summary>
@@ -133,5 +133,4 @@ namespace Telegrator.Core.Descriptors
/// <inheritdoc/> /// <inheritdoc/>
public override string ToString() public override string ToString()
=> DisplayString ?? From.HandlerType.Name; => DisplayString ?? From.HandlerType.Name;
}
} }
@@ -1,15 +1,15 @@
using Telegrator.Aspects; using Telegrator.Aspects;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Manages the execution of pre and post-execution aspects for a handler.
/// This class coordinates between self-processing (handler implements interfaces)
/// and typed processing (external processor classes).
/// </summary>
public sealed class DescriptorAspectsSet
{ {
/// <summary>
/// Manages the execution of pre and post-execution aspects for a handler.
/// This class coordinates between self-processing (handler implements interfaces)
/// and typed processing (external processor classes).
/// </summary>
public sealed class DescriptorAspectsSet
{
/// <summary> /// <summary>
/// Gets the type of the external pre-processor, if specified via <see cref="BeforeExecutionAttribute{T}"/>. /// Gets the type of the external pre-processor, if specified via <see cref="BeforeExecutionAttribute{T}"/>.
/// </summary> /// </summary>
@@ -76,5 +76,4 @@ namespace Telegrator.Core.Descriptors
return Result.Ok(); return Result.Ok();
} }
}
} }
@@ -3,13 +3,13 @@ using Telegrator.Core.Filters;
using Telegrator.Handlers.Diagnostics; using Telegrator.Handlers.Diagnostics;
using Telegrator.Logging; using Telegrator.Logging;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Represents a set of filters for a handler descriptor, including update and state keeper validators.
/// </summary>
public sealed class DescriptorFiltersSet
{ {
/// <summary>
/// Represents a set of filters for a handler descriptor, including update and state keeper validators.
/// </summary>
public sealed class DescriptorFiltersSet
{
/// <summary> /// <summary>
/// Validator for the update object. /// Validator for the update object.
/// </summary> /// </summary>
@@ -141,5 +141,4 @@ namespace Telegrator.Core.Descriptors
return false; return false;
} }
} }
}
} }
@@ -1,12 +1,12 @@
using Telegrator.Core.Attributes; using Telegrator.Core.Attributes;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Represents an indexer for handler descriptors, containing importance and priority information.
/// </summary>
public readonly struct DescriptorIndexer(int routerIndex, int importance, int priority) : IComparable<DescriptorIndexer>
{ {
/// <summary>
/// Represents an indexer for handler descriptors, containing importance and priority information.
/// </summary>
public readonly struct DescriptorIndexer(int routerIndex, int importance, int priority) : IComparable<DescriptorIndexer>
{
/// <summary> /// <summary>
/// Index of this descriptor when it was added to router /// Index of this descriptor when it was added to router
/// </summary> /// </summary>
@@ -84,5 +84,4 @@ namespace Telegrator.Core.Descriptors
{ {
return string.Format("(Ix: {0,2}, Im: {1,2}, Pr: {2,2})", RouterIndex, Importance, Priority); return string.Format("(Ix: {0,2}, Im: {1,2}, Pr: {2,2})", RouterIndex, Importance, Priority);
} }
}
} }
@@ -4,13 +4,13 @@ using Telegrator.Core.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Specifies the type of handler descriptor.
/// </summary>
public enum DescriptorType
{ {
/// <summary>
/// Specifies the type of handler descriptor.
/// </summary>
public enum DescriptorType
{
/// <summary> /// <summary>
/// General handler descriptor. /// General handler descriptor.
/// </summary> /// </summary>
@@ -30,13 +30,13 @@ namespace Telegrator.Core.Descriptors
/// Singleton handler descriptor (single instance). /// Singleton handler descriptor (single instance).
/// </summary> /// </summary>
Singleton Singleton
} }
/// <summary> /// <summary>
/// Describes a handler, its type, filters, and instantiation logic. /// Describes a handler, its type, filters, and instantiation logic.
/// </summary> /// </summary>
public class HandlerDescriptor public class HandlerDescriptor
{ {
/// <summary> /// <summary>
/// The type of the descriptor. /// The type of the descriptor.
/// </summary> /// </summary>
@@ -471,5 +471,4 @@ namespace Telegrator.Core.Descriptors
/// <inheritdoc/> /// <inheritdoc/>
public override string ToString() public override string ToString()
=> DisplayString ?? HandlerType.Name; => DisplayString ?? HandlerType.Name;
}
} }
@@ -2,13 +2,13 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// The collection containing the <see cref="HandlerDescriptor"/>'s. Used to route <see cref="Update"/>'s in <see cref="IHandlersProvider"/>
/// </summary>
public sealed class HandlerDescriptorList : IEnumerable<HandlerDescriptor>
{ {
/// <summary>
/// The collection containing the <see cref="HandlerDescriptor"/>'s. Used to route <see cref="Update"/>'s in <see cref="IHandlersProvider"/>
/// </summary>
public sealed class HandlerDescriptorList : IEnumerable<HandlerDescriptor>
{
private readonly object _lock = new object(); private readonly object _lock = new object();
private readonly SortedList<DescriptorIndexer, HandlerDescriptor> _innerCollection; private readonly SortedList<DescriptorIndexer, HandlerDescriptor> _innerCollection;
private readonly TelegratorOptions? _options; private readonly TelegratorOptions? _options;
@@ -155,5 +155,4 @@ namespace Telegrator.Core.Descriptors
{ {
return _innerCollection.Values.GetEnumerator(); return _innerCollection.Values.GetEnumerator();
} }
}
} }
@@ -7,13 +7,13 @@ using Telegrator.Aspects;
using Telegrator.Core.Attributes; using Telegrator.Core.Attributes;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Core.Descriptors namespace Telegrator.Core.Descriptors;
/// <summary>
/// Provides methods for inspecting handler types and retrieving their attributes and filters.
/// </summary>
public static class HandlerInspector
{ {
/// <summary>
/// Provides methods for inspecting handler types and retrieving their attributes and filters.
/// </summary>
public static class HandlerInspector
{
/// <summary> /// <summary>
/// Gets handler's display name /// Gets handler's display name
/// </summary> /// </summary>
@@ -95,5 +95,4 @@ namespace Telegrator.Core.Descriptors
Type? typedPost = handlerType.GetCustomAttribute(typeof(AfterExecutionAttribute<>))?.GetType().GetGenericArguments()[0]; Type? typedPost = handlerType.GetCustomAttribute(typeof(AfterExecutionAttribute<>))?.GetType().GetGenericArguments()[0];
return new DescriptorAspectsSet(typedPre, typedPost); return new DescriptorAspectsSet(typedPre, typedPost);
} }
}
} }
@@ -2,13 +2,13 @@
using Telegrator.Filters; using Telegrator.Filters;
using Telegrator.Logging; using Telegrator.Logging;
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// Represents a compiled filter that applies a set of filters to an anonymous target type.
/// </summary>
public class AnonymousCompiledFilter : Filter<Update>, INamedFilter
{ {
/// <summary>
/// Represents a compiled filter that applies a set of filters to an anonymous target type.
/// </summary>
public class AnonymousCompiledFilter : Filter<Update>, INamedFilter
{
private readonly Func<FilterExecutionContext<Update>, object, bool> FilterAction; private readonly Func<FilterExecutionContext<Update>, object, bool> FilterAction;
private readonly Func<Update, object?> GetFilterringTarget; private readonly Func<Update, object?> GetFilterringTarget;
private readonly string _name; private readonly string _name;
@@ -105,5 +105,4 @@ namespace Telegrator.Core.Filters
return false; return false;
} }
} }
}
} }
@@ -2,13 +2,13 @@
using Telegrator.Filters; using Telegrator.Filters;
using Telegrator.Logging; using Telegrator.Logging;
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// Represents a filter that applies a filter action to an anonymous target type extracted from an update.
/// </summary>
public class AnonymousTypeFilter : Filter<Update>, INamedFilter
{ {
/// <summary>
/// Represents a filter that applies a filter action to an anonymous target type extracted from an update.
/// </summary>
public class AnonymousTypeFilter : Filter<Update>, INamedFilter
{
private static readonly Type[] IgnoreLog = [typeof(CompiledFilter<>), typeof(AnonymousCompiledFilter), typeof(AnonymousTypeFilter)]; private static readonly Type[] IgnoreLog = [typeof(CompiledFilter<>), typeof(AnonymousCompiledFilter), typeof(AnonymousTypeFilter)];
private readonly Func<FilterExecutionContext<Update>, object, bool> FilterAction; private readonly Func<FilterExecutionContext<Update>, object, bool> FilterAction;
@@ -106,5 +106,4 @@ namespace Telegrator.Core.Filters
return false; return false;
} }
} }
}
} }
@@ -1,14 +1,14 @@
using Telegrator.Filters; using Telegrator.Filters;
using Telegrator.Logging; using Telegrator.Logging;
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// Represents a filter that composes multiple filters and passes only if all of them pass.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public class CompiledFilter<T> : Filter<T>, INamedFilter where T : class
{ {
/// <summary>
/// Represents a filter that composes multiple filters and passes only if all of them pass.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public class CompiledFilter<T> : Filter<T>, INamedFilter where T : class
{
private readonly IFilter<T>[] Filters; private readonly IFilter<T>[] Filters;
private readonly string _name; private readonly string _name;
@@ -60,5 +60,4 @@ namespace Telegrator.Core.Filters
return true; return true;
} }
}
} }
@@ -1,12 +1,12 @@
using System.Collections; using System.Collections;
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// The list containing filters worked out during Polling to further obtain additional filtering information
/// </summary>
public class CompletedFiltersList : IEnumerable<IFilterCollectable>
{ {
/// <summary>
/// The list containing filters worked out during Polling to further obtain additional filtering information
/// </summary>
public class CompletedFiltersList : IEnumerable<IFilterCollectable>
{
private readonly List<IFilterCollectable> CompletedFilters = []; private readonly List<IFilterCollectable> CompletedFilters = [];
/// <summary> /// <summary>
@@ -82,5 +82,4 @@ namespace Telegrator.Core.Filters
/// <inheritdoc/> /// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => CompletedFilters.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => CompletedFilters.GetEnumerator();
}
} }
@@ -1,14 +1,14 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// Represents the context for filter execution, including update, input, and additional data.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public class FilterExecutionContext<T> where T : class
{ {
/// <summary>
/// Represents the context for filter execution, including update, input, and additional data.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public class FilterExecutionContext<T> where T : class
{
/// <summary> /// <summary>
/// Gets the <see cref="ITelegramBotInfo"/> for the current context. /// Gets the <see cref="ITelegramBotInfo"/> for the current context.
/// </summary> /// </summary>
@@ -82,5 +82,4 @@ namespace Telegrator.Core.Filters
/// <returns>A new <see cref="FilterExecutionContext{C}"/> instance.</returns> /// <returns>A new <see cref="FilterExecutionContext{C}"/> instance.</returns>
public FilterExecutionContext<C> CreateChild<C>(C input) where C : class public FilterExecutionContext<C> CreateChild<C>(C input) where C : class
=> new FilterExecutionContext<C>(UpdateRouter, BotInfo, Update, input, Data, CompletedFilters); => new FilterExecutionContext<C>(UpdateRouter, BotInfo, Update, input, Data, CompletedFilters);
}
} }
+32 -21
View File
@@ -1,39 +1,50 @@
namespace Telegrator.Core.Filters namespace Telegrator.Core.Filters;
/// <summary>
/// Interface for filters that have a name for identification and debugging purposes.
/// </summary>
public interface INamedFilter
{ {
/// <summary>
/// Interface for filters that have a name for identification and debugging purposes.
/// </summary>
public interface INamedFilter
{
/// <summary> /// <summary>
/// Gets the name of the filter. /// Gets the name of the filter.
/// </summary> /// </summary>
public string Name { get; } public string Name { get; }
} }
/// <summary> /// <summary>
/// Interface for filters that can be collected into a completed filters list. /// Interface for filters that can be collected into a completed filters list.
/// Provides information about whether a filter should be tracked during execution. /// Provides information about whether a filter should be tracked during execution.
/// </summary> /// </summary>
public interface IFilterCollectable public interface IFilterCollectable
{ {
/// <summary> /// <summary>
/// Gets if filter can be collected to <see cref="CompletedFiltersList"/> /// Gets if filter can be collected to <see cref="CompletedFiltersList"/>
/// </summary> /// </summary>
public bool IsCollectible { get; } public bool IsCollectible { get; }
} }
/// <summary> /// <summary>
/// Represents a filter for a specific update type. /// Represents a filter for a specific update type.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the update to filter.</typeparam> /// <typeparam name="T">The type of the update to filter.</typeparam>
public interface IFilter<T> : IFilterCollectable where T : class public interface IFilter<T> : IFilterCollectable where T : class
{ {
/// <summary> /// <summary>
/// Determines whether the filter can pass for the given context. /// Determines whether the filter can pass for the given context.
/// </summary> /// </summary>
/// <param name="info">The filter execution context.</param> /// <param name="info">The filter execution context.</param>
/// <returns>True if the filter passes; otherwise, false.</returns> /// <returns>True if the filter passes; otherwise, false.</returns>
public bool CanPass(FilterExecutionContext<T> info); public bool CanPass(FilterExecutionContext<T> info);
} }
/// <summary>
/// Represents a filter that joins multiple filters together.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public interface IJoinedFilter<T> : IFilter<T> where T : class
{
/// <summary>
/// Gets the array of joined filters.
/// </summary>
public IFilter<T>[] Filters { get; }
} }
@@ -1,14 +0,0 @@
namespace Telegrator.Core.Filters
{
/// <summary>
/// Represents a filter that joins multiple filters together.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public interface IJoinedFilter<T> : IFilter<T> where T : class
{
/// <summary>
/// Gets the array of joined filters.
/// </summary>
public IFilter<T>[] Filters { get; }
}
}
@@ -6,13 +6,13 @@ using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
using Telegrator.Handlers; using Telegrator.Handlers;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Abstract handler for Telegram updates of type <typeparamref name="TUpdate"/>.
/// </summary>
public abstract class AbstractUpdateHandler<TUpdate> : UpdateHandlerBase, IHandlerContainerFactory, IAbstractUpdateHandler<TUpdate> where TUpdate : class
{ {
/// <summary>
/// Abstract handler for Telegram updates of type <typeparamref name="TUpdate"/>.
/// </summary>
public abstract class AbstractUpdateHandler<TUpdate> : UpdateHandlerBase, IHandlerContainerFactory, IAbstractUpdateHandler<TUpdate> where TUpdate : class
{
/// <summary> /// <summary>
/// Handler container for the current update. /// Handler container for the current update.
/// </summary> /// </summary>
@@ -92,5 +92,4 @@ namespace Telegrator.Core.Handlers
/// <param name="cancellation">Cancellation token.</param> /// <param name="cancellation">Cancellation token.</param>
/// <returns>A task representing the asynchronous operation.</returns> /// <returns>A task representing the asynchronous operation.</returns>
public abstract Task<Result> Execute(IHandlerContainer<TUpdate> container, CancellationToken cancellation); public abstract Task<Result> Execute(IHandlerContainer<TUpdate> container, CancellationToken cancellation);
}
} }
@@ -6,15 +6,15 @@ using Telegrator.Core.Descriptors;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Handlers; using Telegrator.Handlers;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Abstract base class for handlers that support branching execution based on different methods.
/// Allows multiple handler methods to be defined in a single class, each with its own filters.
/// </summary>
/// <typeparam name="TUpdate">The type of update being handled.</typeparam>
public abstract class BranchingUpdateHandler<TUpdate> : AbstractUpdateHandler<TUpdate>, IHandlerContainerFactory, ICustomDescriptorsProvider where TUpdate : class
{ {
/// <summary>
/// Abstract base class for handlers that support branching execution based on different methods.
/// Allows multiple handler methods to be defined in a single class, each with its own filters.
/// </summary>
/// <typeparam name="TUpdate">The type of update being handled.</typeparam>
public abstract class BranchingUpdateHandler<TUpdate> : AbstractUpdateHandler<TUpdate>, IHandlerContainerFactory, ICustomDescriptorsProvider where TUpdate : class
{
/// <summary> /// <summary>
/// The method info for the current branch being executed. /// The method info for the current branch being executed.
/// </summary> /// </summary>
@@ -161,5 +161,4 @@ namespace Telegrator.Core.Handlers
}; };
} }
} }
}
} }
@@ -5,13 +5,13 @@ using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
using Telegrator.Filters; using Telegrator.Filters;
namespace Telegrator.Core.Handlers.Building namespace Telegrator.Core.Handlers.Building;
/// <summary>
/// Base class for building handler descriptors and managing handler filters.
/// </summary>
public abstract class HandlerBuilderBase(Type buildingHandlerType, UpdateType updateType, IHandlersCollection? handlerCollection) : IHandlerBuilder
{ {
/// <summary>
/// Base class for building handler descriptors and managing handler filters.
/// </summary>
public abstract class HandlerBuilderBase(Type buildingHandlerType, UpdateType updateType, IHandlersCollection? handlerCollection) : IHandlerBuilder
{
private static int HandlerServiceKeyIndex = 0; private static int HandlerServiceKeyIndex = 0;
/// <summary> /// <summary>
@@ -176,5 +176,4 @@ namespace Telegrator.Core.Handlers.Building
AnonymousCompiledFilter compiledPollingFilter = AnonymousCompiledFilter.Compile(filters, getFilterringTarget); AnonymousCompiledFilter compiledPollingFilter = AnonymousCompiledFilter.Compile(filters, getFilterringTarget);
Filters.Add(compiledPollingFilter); Filters.Add(compiledPollingFilter);
} }
}
} }
@@ -1,13 +1,13 @@
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core.Handlers.Building namespace Telegrator.Core.Handlers.Building;
/// <summary>
/// Defines a builder for awaiting handler logic for a specific update type.
/// </summary>
/// <typeparam name="TUpdate">The type of update to await.</typeparam>
public interface IAwaiterHandlerBuilder<TUpdate> : IHandlerBuilder where TUpdate : class
{ {
/// <summary>
/// Defines a builder for awaiting handler logic for a specific update type.
/// </summary>
/// <typeparam name="TUpdate">The type of update to await.</typeparam>
public interface IAwaiterHandlerBuilder<TUpdate> : IHandlerBuilder where TUpdate : class
{
/// <summary> /// <summary>
/// Awaits an update using the specified key resolver and cancellation token. /// Awaits an update using the specified key resolver and cancellation token.
/// </summary> /// </summary>
@@ -15,5 +15,4 @@ namespace Telegrator.Core.Handlers.Building
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A <see cref="Task{TUpdate}"/> representing the awaited update.</returns> /// <returns>A <see cref="Task{TUpdate}"/> representing the awaited update.</returns>
public Task<TUpdate> Await(IStateKeyResolver keyResolver, CancellationToken cancellationToken = default); public Task<TUpdate> Await(IStateKeyResolver keyResolver, CancellationToken cancellationToken = default);
}
} }
@@ -2,13 +2,13 @@
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core.Handlers.Building namespace Telegrator.Core.Handlers.Building;
/// <summary>
/// Defines builder actions for configuring handler builders.
/// </summary>
public interface IHandlerBuilder
{ {
/// <summary>
/// Defines builder actions for configuring handler builders.
/// </summary>
public interface IHandlerBuilder
{
/// <summary> /// <summary>
/// Sets the update validating action for the handler. /// Sets the update validating action for the handler.
/// </summary> /// </summary>
@@ -82,5 +82,4 @@ namespace Telegrator.Core.Handlers.Building
/// <returns>The builder instance.</returns> /// <returns>The builder instance.</returns>
public void AddTargetedFilters<TFilterTarget>(Func<Update, TFilterTarget?> getFilterringTarget, params IFilter<TFilterTarget>[] filters) public void AddTargetedFilters<TFilterTarget>(Func<Update, TFilterTarget?> getFilterringTarget, params IFilter<TFilterTarget>[] filters)
where TFilterTarget : class; where TFilterTarget : class;
}
} }
@@ -1,17 +1,16 @@
using Telegrator.Handlers.Building; using Telegrator.Handlers.Building;
namespace Telegrator.Core.Handlers.Building namespace Telegrator.Core.Handlers.Building;
/// <summary>
/// Defines a builder for regular handler logic for a specific update type.
/// </summary>
/// <typeparam name="TUpdate">The type of update to handle.</typeparam>
public interface IRegularHandlerBuilder<TUpdate> : IHandlerBuilder where TUpdate : class
{ {
/// <summary>
/// Defines a builder for regular handler logic for a specific update type.
/// </summary>
/// <typeparam name="TUpdate">The type of update to handle.</typeparam>
public interface IRegularHandlerBuilder<TUpdate> : IHandlerBuilder where TUpdate : class
{
/// <summary> /// <summary>
/// Builds the handler logic using the specified execution delegate. /// Builds the handler logic using the specified execution delegate.
/// </summary> /// </summary>
/// <param name="executeHandler">The delegate to execute the handler logic.</param> /// <param name="executeHandler">The delegate to execute the handler logic.</param>
public IHandlersCollection Build(AbstractHandlerAction<TUpdate> executeHandler); public IHandlersCollection Build(AbstractHandlerAction<TUpdate> executeHandler);
}
} }
@@ -1,20 +1,20 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Core.Handlers.Building namespace Telegrator.Core.Handlers.Building;
{
/// <summary>
/// Delegate for validating an update in a filter context.
/// </summary>
/// <param name="context">The filter execution context.</param>
/// <returns>True if the update is valid; otherwise, false.</returns>
public delegate bool UpdateValidateAction(FilterExecutionContext<Update> context);
/// <summary> /// <summary>
/// Filter that uses a delegate to validate updates. /// Delegate for validating an update in a filter context.
/// </summary> /// </summary>
public class UpdateValidateFilter : IFilter<Update> /// <param name="context">The filter execution context.</param>
{ /// <returns>True if the update is valid; otherwise, false.</returns>
public delegate bool UpdateValidateAction(FilterExecutionContext<Update> context);
/// <summary>
/// Filter that uses a delegate to validate updates.
/// </summary>
public class UpdateValidateFilter : IFilter<Update>
{
/// <summary> /// <summary>
/// Gets a value indicating whether this filter is collectable. Always false for this filter. /// Gets a value indicating whether this filter is collectable. Always false for this filter.
/// </summary> /// </summary>
@@ -37,5 +37,4 @@ namespace Telegrator.Core.Handlers.Building
/// <returns>True if the filter passes; otherwise, false.</returns> /// <returns>True if the filter passes; otherwise, false.</returns>
public bool CanPass(FilterExecutionContext<Update> info) public bool CanPass(FilterExecutionContext<Update> info)
=> UpdateValidateAction.Invoke(info); => UpdateValidateAction.Invoke(info);
}
} }
@@ -3,13 +3,13 @@ using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Represents an empty handler container that throws <see cref="NotImplementedException"/> for all members.
/// </summary>
public class EmptyHandlerContainer : IHandlerContainer
{ {
/// <summary>
/// Represents an empty handler container that throws <see cref="NotImplementedException"/> for all members.
/// </summary>
public class EmptyHandlerContainer : IHandlerContainer
{
/// <inheritdoc/> /// <inheritdoc/>
public Update HandlingUpdate => throw new NotImplementedException(); public Update HandlingUpdate => throw new NotImplementedException();
@@ -27,5 +27,4 @@ namespace Telegrator.Core.Handlers
/// <inheritdoc/> /// <inheritdoc/>
public IStateStorage StateStorage => throw new NotImplementedException(); public IStateStorage StateStorage => throw new NotImplementedException();
}
} }
@@ -1,10 +1,10 @@
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Represents a token that tracks the lifetime of a handler instance.
/// </summary>
public class HandlerLifetimeToken
{ {
/// <summary>
/// Represents a token that tracks the lifetime of a handler instance.
/// </summary>
public class HandlerLifetimeToken
{
/// <summary> /// <summary>
/// Event triggered when the handler's lifetime has ended. /// Event triggered when the handler's lifetime has ended.
/// </summary> /// </summary>
@@ -23,5 +23,4 @@
IsEnded = true; IsEnded = true;
OnLifetimeEnded?.Invoke(this); OnLifetimeEnded?.Invoke(this);
} }
}
} }
@@ -3,14 +3,14 @@ using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Interface for handler containers that provide context and resources for update handlers.
/// Contains all necessary information and services that handlers need during execution.
/// </summary>
public interface IHandlerContainer
{ {
/// <summary>
/// Interface for handler containers that provide context and resources for update handlers.
/// Contains all necessary information and services that handlers need during execution.
/// </summary>
public interface IHandlerContainer
{
/// <summary> /// <summary>
/// Gets the <see cref="Update"/> being handled. /// Gets the <see cref="Update"/> being handled.
/// </summary> /// </summary>
@@ -40,5 +40,4 @@ namespace Telegrator.Core.Handlers
/// Gets the <see cref="IStateStorage"/> for state managment. /// Gets the <see cref="IStateStorage"/> for state managment.
/// </summary> /// </summary>
public IStateStorage StateStorage { get; } public IStateStorage StateStorage { get; }
}
} }
@@ -1,18 +1,17 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Factory interface for creating handler containers.
/// Provides a way to create handler containers with specific providers and handler information.
/// </summary>
public interface IHandlerContainerFactory
{ {
/// <summary>
/// Factory interface for creating handler containers.
/// Provides a way to create handler containers with specific providers and handler information.
/// </summary>
public interface IHandlerContainerFactory
{
/// <summary> /// <summary>
/// Creates a new <see cref="IHandlerContainer"/> for the specified awaiting provider and handler info. /// Creates a new <see cref="IHandlerContainer"/> for the specified awaiting provider and handler info.
/// </summary> /// </summary>
/// <param name="handlerInfo">The <see cref="DescribedHandlerDescriptor"/> for the handler.</param> /// <param name="handlerInfo">The <see cref="DescribedHandlerDescriptor"/> for the handler.</param>
/// <returns>A new <see cref="IHandlerContainer"/> instance.</returns> /// <returns>A new <see cref="IHandlerContainer"/> instance.</returns>
public IHandlerContainer CreateContainer(DescribedHandlerDescriptor handlerInfo); public IHandlerContainer CreateContainer(DescribedHandlerDescriptor handlerInfo);
}
} }
@@ -4,13 +4,13 @@ using Telegram.Bot.Types.Enums;
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
using Telegrator.Handlers.Diagnostics; using Telegrator.Handlers.Diagnostics;
namespace Telegrator.Core.Handlers namespace Telegrator.Core.Handlers;
/// <summary>
/// Base class for update handlers, providing execution and lifetime management for Telegram updates.
/// </summary>
public abstract class UpdateHandlerBase(UpdateType handlingUpdateType) : IUpdateHandlerBase
{ {
/// <summary>
/// Base class for update handlers, providing execution and lifetime management for Telegram updates.
/// </summary>
public abstract class UpdateHandlerBase(UpdateType handlingUpdateType) : IUpdateHandlerBase
{
/// <summary> /// <summary>
/// Gets the <see cref="UpdateType"/> that this handler processes. /// Gets the <see cref="UpdateType"/> that this handler processes.
/// </summary> /// </summary>
@@ -178,5 +178,4 @@ namespace Telegrator.Core.Handlers
if (Dispose(true)) if (Dispose(true))
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
}
} }
+6 -7
View File
@@ -1,17 +1,16 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Provider for managing awaiting handlers that can wait for specific update types.
/// </summary>
public interface IAwaitingProvider : IHandlersProvider
{ {
/// <summary>
/// Provider for managing awaiting handlers that can wait for specific update types.
/// </summary>
public interface IAwaitingProvider : IHandlersProvider
{
/// <summary> /// <summary>
/// Registers the usage of a handler and returns a disposable object to manage its lifetime. /// Registers the usage of a handler and returns a disposable object to manage its lifetime.
/// </summary> /// </summary>
/// <param name="handlerDescriptor">The <see cref="HandlerDescriptor"/> to use.</param> /// <param name="handlerDescriptor">The <see cref="HandlerDescriptor"/> to use.</param>
/// <returns>An <see cref="IDisposable"/> that manages the handler's usage lifetime.</returns> /// <returns>An <see cref="IDisposable"/> that manages the handler's usage lifetime.</returns>
public IDisposable UseHandler(HandlerDescriptor handlerDescriptor); public IDisposable UseHandler(HandlerDescriptor handlerDescriptor);
}
} }
+7 -8
View File
@@ -1,14 +1,13 @@
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Interface for providers that collect and manage handler collections.
/// Provides access to a collection of handlers for various processing operations.
/// </summary>
public interface ICollectingProvider
{ {
/// <summary>
/// Interface for providers that collect and manage handler collections.
/// Provides access to a collection of handlers for various processing operations.
/// </summary>
public interface ICollectingProvider
{
/// <summary> /// <summary>
/// Gets the collection of handlers managed by this provider. /// Gets the collection of handlers managed by this provider.
/// </summary> /// </summary>
public IHandlersCollection Handlers { get; } public IHandlersCollection Handlers { get; }
}
} }
@@ -1,17 +1,16 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Interface for classes that can provide custom handler descriptors.
/// Allows classes to define their own handler description logic beyond the standard reflection-based approach.
/// </summary>
public interface ICustomDescriptorsProvider
{ {
/// <summary>
/// Interface for classes that can provide custom handler descriptors.
/// Allows classes to define their own handler description logic beyond the standard reflection-based approach.
/// </summary>
public interface ICustomDescriptorsProvider
{
/// <summary> /// <summary>
/// Describes the handlers provided by this class. /// Describes the handlers provided by this class.
/// </summary> /// </summary>
/// <returns>A collection of handler descriptors.</returns> /// <returns>A collection of handler descriptors.</returns>
public IEnumerable<HandlerDescriptor> DescribeHandlers(); public IEnumerable<HandlerDescriptor> DescribeHandlers();
}
} }
+7 -8
View File
@@ -1,14 +1,14 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Collection class for managing handler descriptors organized by update type.
/// Provides functionality for collecting, adding, and organizing handlers.
/// </summary>
public interface IHandlersCollection
{ {
/// <summary>
/// Collection class for managing handler descriptors organized by update type.
/// Provides functionality for collecting, adding, and organizing handlers.
/// </summary>
public interface IHandlersCollection
{
/// <summary> /// <summary>
/// Gets the collection of <see cref="UpdateType"/>'s allowed by registered handlers /// Gets the collection of <see cref="UpdateType"/>'s allowed by registered handlers
/// </summary> /// </summary>
@@ -37,5 +37,4 @@ namespace Telegrator.Core
/// <param name="descriptor">The handler descriptor to add.</param> /// <param name="descriptor">The handler descriptor to add.</param>
/// <returns>The updated <see cref="IHandlersCollection"/>.</returns> /// <returns>The updated <see cref="IHandlersCollection"/>.</returns>
public IHandlersCollection AddDescriptor(HandlerDescriptor descriptor); public IHandlersCollection AddDescriptor(HandlerDescriptor descriptor);
}
} }
+8 -9
View File
@@ -1,11 +1,10 @@
namespace Telegrator.Core namespace Telegrator.Core;
{
/// <summary> /// <summary>
/// Combines <see cref="IHandlersCollection"/> and <see cref="IHandlersProvider"/>. /// Combines <see cref="IHandlersCollection"/> and <see cref="IHandlersProvider"/>.
/// Provides functionality of collecting, organizing and resolving handlers instances. /// Provides functionality of collecting, organizing and resolving handlers instances.
/// </summary> /// </summary>
public interface IHandlersManager : IHandlersCollection, IHandlersProvider public interface IHandlersManager : IHandlersCollection, IHandlersProvider
{ {
}
} }
+6 -7
View File
@@ -2,13 +2,13 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Provides methods to retrieve and describe handler information for updates.
/// </summary>
public interface IHandlersProvider
{ {
/// <summary>
/// Provides methods to retrieve and describe handler information for updates.
/// </summary>
public interface IHandlersProvider
{
/// <summary> /// <summary>
/// Gets the collection of <see cref="UpdateType"/>'s allowed by registered handlers /// Gets the collection of <see cref="UpdateType"/>'s allowed by registered handlers
/// </summary> /// </summary>
@@ -36,5 +36,4 @@ namespace Telegrator.Core
/// </summary> /// </summary>
/// <returns>True if the provider is empty; otherwise, false.</returns> /// <returns>True if the provider is empty; otherwise, false.</returns>
public bool IsEmpty(); public bool IsEmpty();
}
} }
@@ -1,14 +1,14 @@
using Telegram.Bot; using Telegram.Bot;
using Telegram.Bot.Polling; using Telegram.Bot.Polling;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Interface for handling exceptions that occur during update routing operations.
/// Provides a centralized way to handle and log errors that occur during bot operation.
/// </summary>
public interface IRouterExceptionHandler
{ {
/// <summary>
/// Interface for handling exceptions that occur during update routing operations.
/// Provides a centralized way to handle and log errors that occur during bot operation.
/// </summary>
public interface IRouterExceptionHandler
{
/// <summary> /// <summary>
/// Handles exceptions that occur during update routing. /// Handles exceptions that occur during update routing.
/// </summary> /// </summary>
@@ -17,5 +17,4 @@ namespace Telegrator.Core
/// <param name="source">The <see cref="HandleErrorSource"/> indicating the source of the error.</param> /// <param name="source">The <see cref="HandleErrorSource"/> indicating the source of the error.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
public void HandleException(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken); public void HandleException(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken);
}
} }
+7 -8
View File
@@ -1,16 +1,15 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Interface for providing bot information and metadata.
/// Contains information about the bot user and provides initialization capabilities.
/// </summary>
public interface ITelegramBotInfo
{ {
/// <summary>
/// Interface for providing bot information and metadata.
/// Contains information about the bot user and provides initialization capabilities.
/// </summary>
public interface ITelegramBotInfo
{
/// <summary> /// <summary>
/// Gets the <see cref="User"/> representing the bot. /// Gets the <see cref="User"/> representing the bot.
/// </summary> /// </summary>
public User User { get; } public User User { get; }
}
} }
+18 -19
View File
@@ -1,24 +1,24 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Represents a delegate for when a handler is enqueued.
/// </summary>
/// <param name="args">The <see cref="DescribedHandlerDescriptor"/> for the enqueued handler.</param>
public delegate void HandlerEnqueued(DescribedHandlerDescriptor args);
/// <summary>
/// Represents a delegate for when a handler is executing.
/// </summary>
/// <param name="args">The <see cref="DescribedHandlerDescriptor"/> for the executing handler.</param>
public delegate void HandlerExecuting(DescribedHandlerDescriptor args);
/// <summary>
/// Provides a pool for managing the execution and queuing of update handlers.
/// </summary>
public interface IUpdateHandlersPool : IDisposable
{ {
/// <summary>
/// Represents a delegate for when a handler is enqueued.
/// </summary>
/// <param name="args">The <see cref="DescribedHandlerDescriptor"/> for the enqueued handler.</param>
public delegate void HandlerEnqueued(DescribedHandlerDescriptor args);
/// <summary>
/// Represents a delegate for when a handler is executing.
/// </summary>
/// <param name="args">The <see cref="DescribedHandlerDescriptor"/> for the executing handler.</param>
public delegate void HandlerExecuting(DescribedHandlerDescriptor args);
/// <summary>
/// Provides a pool for managing the execution and queuing of update handlers.
/// </summary>
public interface IUpdateHandlersPool : IDisposable
{
/// <summary> /// <summary>
/// Occurs when a handler is enqueued. /// Occurs when a handler is enqueued.
/// </summary> /// </summary>
@@ -34,5 +34,4 @@ namespace Telegrator.Core
/// </summary> /// </summary>
/// <param name="handlers">The handlers to enqueue.</param> /// <param name="handlers">The handlers to enqueue.</param>
public Task Enqueue(params IEnumerable<DescribedHandlerDescriptor> handlers); public Task Enqueue(params IEnumerable<DescribedHandlerDescriptor> handlers);
}
} }
+7 -8
View File
@@ -2,14 +2,14 @@
using Telegrator.Core.Handlers; using Telegrator.Core.Handlers;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Core namespace Telegrator.Core;
/// <summary>
/// Interface for update routers that handle incoming updates and manage handler execution.
/// Combines update handling capabilities with polling provider functionality and exception handling.
/// </summary>
public interface IUpdateRouter : IUpdateHandler
{ {
/// <summary>
/// Interface for update routers that handle incoming updates and manage handler execution.
/// Combines update handling capabilities with polling provider functionality and exception handling.
/// </summary>
public interface IUpdateRouter : IUpdateHandler
{
/// <summary> /// <summary>
/// Gets the <see cref="TelegratorOptions"/> for the router. /// Gets the <see cref="TelegratorOptions"/> for the router.
/// </summary> /// </summary>
@@ -44,5 +44,4 @@ namespace Telegrator.Core
/// Default hand;er container factory /// Default hand;er container factory
/// </summary> /// </summary>
public IHandlerContainerFactory? DefaultContainerFactory { get; set; } public IHandlerContainerFactory? DefaultContainerFactory { get; set; }
}
} }
+32 -33
View File
@@ -1,11 +1,11 @@
namespace Telegrator namespace Telegrator;
/// <summary>
/// Enumeration of dice types supported by Telegram.
/// Used for filtering dice messages and determining dice emoji representations.
/// </summary>
public enum DiceType
{ {
/// <summary>
/// Enumeration of dice types supported by Telegram.
/// Used for filtering dice messages and determining dice emoji representations.
/// </summary>
public enum DiceType
{
/// <summary> /// <summary>
/// Standard dice (🎲). /// Standard dice (🎲).
/// </summary> /// </summary>
@@ -35,15 +35,15 @@
/// Casino slot machine (🎰). /// Casino slot machine (🎰).
/// </summary> /// </summary>
Casino Casino
} }
/// <summary> /// <summary>
/// Flags version of <see cref="Telegram.Bot.Types.Enums.ChatType"/> /// Flags version of <see cref="Telegram.Bot.Types.Enums.ChatType"/>
/// Type of the <see cref="Telegram.Bot.Types.Chat"/>, from which the message or inline query was sent /// Type of the <see cref="Telegram.Bot.Types.Chat"/>, from which the message or inline query was sent
/// </summary> /// </summary>
[Flags] [Flags]
public enum ChatTypeFlags public enum ChatTypeFlags
{ {
/// <summary> /// <summary>
/// Normal one-to-one chat with a user or bot /// Normal one-to-one chat with a user or bot
/// </summary> /// </summary>
@@ -68,14 +68,14 @@
/// Value possible only in <see cref="Telegram.Bot.Types.InlineQuery.ChatType"/>: private chat with the inline query sender /// Value possible only in <see cref="Telegram.Bot.Types.InlineQuery.ChatType"/>: private chat with the inline query sender
/// </summary> /// </summary>
Sender Sender
} }
/* /*
/// <summary> /// <summary>
/// Messages from where this filter was originated /// Messages from where this filter was originated
/// </summary> /// </summary>
public enum FilterOrigin public enum FilterOrigin
{ {
/// <summary> /// <summary>
/// None, empty filter /// None, empty filter
/// </summary> /// </summary>
@@ -95,16 +95,16 @@
/// From regular <see cref="Attributes.UpdateFilterAttribute{T}"/> /// From regular <see cref="Attributes.UpdateFilterAttribute{T}"/>
/// </summary> /// </summary>
Regualr Regualr
} }
*/ */
/* /*
/// <summary> /// <summary>
/// Levels of debug writing /// Levels of debug writing
/// </summary> /// </summary>
[Flags] [Flags]
public enum DebugLevel public enum DebugLevel
{ {
/// <summary> /// <summary>
/// None to write /// None to write
/// </summary> /// </summary>
@@ -129,6 +129,5 @@
/// Write debug messages from handlers pool execution /// Write debug messages from handlers pool execution
/// </summary> /// </summary>
HandlersPool = 0x8 HandlersPool = 0x8
}
*/
} }
*/
+19 -20
View File
@@ -1,38 +1,38 @@
using Telegrator.Core.Descriptors; using Telegrator.Core.Descriptors;
namespace Telegrator namespace Telegrator;
/// <summary>
/// Exception thrown when attempting to modify a frozen collection.
/// </summary>
public class CollectionFrozenException : Exception
{ {
/// <summary>
/// Exception thrown when attempting to modify a frozen collection.
/// </summary>
public class CollectionFrozenException : Exception
{
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CollectionFrozenException"/> class. /// Initializes a new instance of the <see cref="CollectionFrozenException"/> class.
/// </summary> /// </summary>
public CollectionFrozenException() public CollectionFrozenException()
: base("Can't change a frozen collection.") { } : base("Can't change a frozen collection.") { }
} }
/// <summary> /// <summary>
/// Exception thrown when a type is not a valid filter type. /// Exception thrown when a type is not a valid filter type.
/// </summary> /// </summary>
public class NotFilterTypeException : Exception public class NotFilterTypeException : Exception
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="NotFilterTypeException"/> class. /// Initializes a new instance of the <see cref="NotFilterTypeException"/> class.
/// </summary> /// </summary>
/// <param name="type">The type that is not a filter type.</param> /// <param name="type">The type that is not a filter type.</param>
public NotFilterTypeException(Type type) public NotFilterTypeException(Type type)
: base(string.Format("\"{0}\" is not a filter type", type.Name)) { } : base(string.Format("\"{0}\" is not a filter type", type.Name)) { }
} }
/// <summary> /// <summary>
/// Exception thrown when a handler execution fails. /// Exception thrown when a handler execution fails.
/// Contains information about the handler and the inner exception. /// Contains information about the handler and the inner exception.
/// </summary> /// </summary>
public class HandlerFaultedException : Exception public class HandlerFaultedException : Exception
{ {
/// <summary> /// <summary>
/// The handler info associated with the faulted handler. /// The handler info associated with the faulted handler.
/// </summary> /// </summary>
@@ -48,5 +48,4 @@ namespace Telegrator
{ {
HandlerInfo = handlerInfo; HandlerInfo = handlerInfo;
} }
}
} }
+18 -19
View File
@@ -2,13 +2,13 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Filter thet checks <see cref="CallbackQuery"/>'s data
/// </summary>
public class CallbackDataFilter : Filter<CallbackQuery>
{ {
/// <summary>
/// Filter thet checks <see cref="CallbackQuery"/>'s data
/// </summary>
public class CallbackDataFilter : Filter<CallbackQuery>
{
private readonly string _data; private readonly string _data;
/// <summary> /// <summary>
@@ -25,13 +25,13 @@ namespace Telegrator.Filters
{ {
return context.Input.Data == _data; return context.Input.Data == _data;
} }
} }
/// <summary> /// <summary>
/// Filter that checks if <see cref="CallbackQuery"/> belongs to a specific message /// Filter that checks if <see cref="CallbackQuery"/> belongs to a specific message
/// </summary> /// </summary>
public class CallbackInlineIdFilter : Filter<CallbackQuery> public class CallbackInlineIdFilter : Filter<CallbackQuery>
{ {
private readonly string _inlineMessageId; private readonly string _inlineMessageId;
/// <summary> /// <summary>
@@ -48,13 +48,13 @@ namespace Telegrator.Filters
{ {
return context.Input.InlineMessageId == _inlineMessageId; return context.Input.InlineMessageId == _inlineMessageId;
} }
} }
/// <summary> /// <summary>
/// Filters callback queries by matching their data with a regular expression. /// Filters callback queries by matching their data with a regular expression.
/// </summary> /// </summary>
public class CallbackRegexFilter : RegexFilterBase<CallbackQuery> public class CallbackRegexFilter : RegexFilterBase<CallbackQuery>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CallbackRegexFilter"/> class with a pattern and options. /// Initializes a new instance of the <see cref="CallbackRegexFilter"/> class with a pattern and options.
/// </summary> /// </summary>
@@ -69,5 +69,4 @@ namespace Telegrator.Filters
/// <param name="regex">The regex object.</param> /// <param name="regex">The regex object.</param>
public CallbackRegexFilter(Regex regex) public CallbackRegexFilter(Regex regex)
: base(clb => clb.Data, regex) { } : base(clb => clb.Data, regex) { }
}
} }
+8 -9
View File
@@ -2,15 +2,15 @@
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Handlers; using Telegrator.Handlers;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Filter that checks if a command matches any of the specified aliases.
/// Requires a <see cref="CommandHandlerAttribute"/> to be applied first to extract the command.
/// </summary>
/// <param name="alliases">The command aliases to check against.</param>
public class CommandAlliasFilter(params string[] alliases) : Filter<Message>
{ {
/// <summary>
/// Filter that checks if a command matches any of the specified aliases.
/// Requires a <see cref="CommandHandlerAttribute"/> to be applied first to extract the command.
/// </summary>
/// <param name="alliases">The command aliases to check against.</param>
public class CommandAlliasFilter(params string[] alliases) : Filter<Message>
{
/// <summary> /// <summary>
/// Gets the command that was received and extracted by the <see cref="CommandHandlerAttribute"/>. /// Gets the command that was received and extracted by the <see cref="CommandHandlerAttribute"/>.
/// </summary> /// </summary>
@@ -28,5 +28,4 @@ namespace Telegrator.Filters
ReceivedCommand = context.CompletedFilters.Get<CommandHandlerAttribute>(0).ReceivedCommand; ReceivedCommand = context.CompletedFilters.Get<CommandHandlerAttribute>(0).ReceivedCommand;
return alliases.Contains(ReceivedCommand, StringComparer.InvariantCultureIgnoreCase); return alliases.Contains(ReceivedCommand, StringComparer.InvariantCultureIgnoreCase);
} }
}
} }
+59 -60
View File
@@ -3,15 +3,15 @@ using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Handlers; using Telegrator.Handlers;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Abstract base class for filters that operate on command arguments.
/// Provides functionality to extract and validate command arguments from message text.
/// </summary>
/// <param name="index">The index of the argument to filter (0-based).</param>
public abstract class CommandArgumentFilterBase(int index) : Filter<Message>
{ {
/// <summary>
/// Abstract base class for filters that operate on command arguments.
/// Provides functionality to extract and validate command arguments from message text.
/// </summary>
/// <param name="index">The index of the argument to filter (0-based).</param>
public abstract class CommandArgumentFilterBase(int index) : Filter<Message>
{
/// <summary> /// <summary>
/// Gets the chosen argument at the specified index. /// Gets the chosen argument at the specified index.
/// </summary> /// </summary>
@@ -40,14 +40,14 @@ namespace Telegrator.Filters
/// <param name="context">The filter execution context.</param> /// <param name="context">The filter execution context.</param>
/// <returns>True if the filter passes; otherwise, false.</returns> /// <returns>True if the filter passes; otherwise, false.</returns>
protected abstract bool CanPassNext(FilterExecutionContext<Message> context); protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
} }
/// <summary> /// <summary>
/// Filter that checks if a command has arguments count >= <paramref name="count"/>. /// Filter that checks if a command has arguments count >= <paramref name="count"/>.
/// </summary> /// </summary>
/// <param name="count"></param> /// <param name="count"></param>
public class ArgumentCountFilter(int count) : Filter<Message> public class ArgumentCountFilter(int count) : Filter<Message>
{ {
private readonly int Count = count; private readonly int Count = count;
/// <inheritdoc/> /// <inheritdoc/>
@@ -57,16 +57,16 @@ namespace Telegrator.Filters
string[] args = attr.Arguments ??= context.Input.SplitArgs(); string[] args = attr.Arguments ??= context.Input.SplitArgs();
return args.Length >= Count; return args.Length >= Count;
} }
} }
/// <summary> /// <summary>
/// Filter that checks if a command argument starts with a specified content. /// Filter that checks if a command argument starts with a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the argument starts with.</param> /// <param name="content">The content to check if the argument starts with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index) public class ArgumentStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
{ {
/// <summary> /// <summary>
/// The content to check if the argument starts with. /// The content to check if the argument starts with.
/// </summary> /// </summary>
@@ -84,16 +84,16 @@ namespace Telegrator.Filters
/// <returns>True if the argument starts with the specified content; otherwise, false.</returns> /// <returns>True if the argument starts with the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Target.StartsWith(Content, Comparison); => Target.StartsWith(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if a command argument ends with a specified content. /// Filter that checks if a command argument ends with a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the argument ends with.</param> /// <param name="content">The content to check if the argument ends with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index) public class ArgumentEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
{ {
/// <summary> /// <summary>
/// The content to check if the argument ends with. /// The content to check if the argument ends with.
/// </summary> /// </summary>
@@ -111,16 +111,16 @@ namespace Telegrator.Filters
/// <returns>True if the argument ends with the specified content; otherwise, false.</returns> /// <returns>True if the argument ends with the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Target.EndsWith(Content, Comparison); => Target.EndsWith(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if a command argument contains a specified content. /// Filter that checks if a command argument contains a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the argument contains.</param> /// <param name="content">The content to check if the argument contains.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index) public class ArgumentContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
{ {
/// <summary> /// <summary>
/// The content to check if the argument contains. /// The content to check if the argument contains.
/// </summary> /// </summary>
@@ -138,16 +138,16 @@ namespace Telegrator.Filters
/// <returns>True if the argument contains the specified content; otherwise, false.</returns> /// <returns>True if the argument contains the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Target.IndexOf(Content, Comparison) >= 0; => Target.IndexOf(Content, Comparison) >= 0;
} }
/// <summary> /// <summary>
/// Filter that checks if a command argument equals a specified content. /// Filter that checks if a command argument equals a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the argument equals.</param> /// <param name="content">The content to check if the argument equals.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index) public class ArgumentEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
{ {
/// <summary> /// <summary>
/// The content to check if the argument equals. /// The content to check if the argument equals.
/// </summary> /// </summary>
@@ -165,15 +165,15 @@ namespace Telegrator.Filters
/// <returns>True if the argument equals the specified content; otherwise, false.</returns> /// <returns>True if the argument equals the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Target.Equals(Content, Comparison); => Target.Equals(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if a command argument matches a regular expression pattern. /// Filter that checks if a command argument matches a regular expression pattern.
/// </summary> /// </summary>
/// <param name="regex">The regular expression to match against the argument.</param> /// <param name="regex">The regular expression to match against the argument.</param>
/// <param name="index">The index of the argument to check (0-based).</param> /// <param name="index">The index of the argument to check (0-based).</param>
public class ArgumentRegexFilter(Regex regex, int index = 0) : CommandArgumentFilterBase(index) public class ArgumentRegexFilter(Regex regex, int index = 0) : CommandArgumentFilterBase(index)
{ {
private readonly Regex _regex = regex; private readonly Regex _regex = regex;
/// <summary> /// <summary>
@@ -201,5 +201,4 @@ namespace Telegrator.Filters
Match = _regex.Match(Target); Match = _regex.Match(Target);
return Match.Success; return Match.Success;
} }
}
} }
+28 -29
View File
@@ -2,14 +2,14 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Abstract base class for filters that operate based on the current environment.
/// Provides functionality to detect debug vs release environments.
/// </summary>
public abstract class EnvironmentFilter : Filter<Update>
{ {
/// <summary>
/// Abstract base class for filters that operate based on the current environment.
/// Provides functionality to detect debug vs release environments.
/// </summary>
public abstract class EnvironmentFilter : Filter<Update>
{
/// <summary> /// <summary>
/// Gets a value indicating whether the current environment is debug mode. /// Gets a value indicating whether the current environment is debug mode.
/// This is set during static initialization based on the DEBUG conditional compilation symbol. /// This is set during static initialization based on the DEBUG conditional compilation symbol.
@@ -28,13 +28,13 @@ namespace Telegrator.Filters
[Conditional("DEBUG")] [Conditional("DEBUG")]
private static void SetIsCurrentEnvDebug() private static void SetIsCurrentEnvDebug()
=> IsCurrentEnvDebug = true; => IsCurrentEnvDebug = true;
} }
/// <summary> /// <summary>
/// Filter that only passes in debug environment builds. /// Filter that only passes in debug environment builds.
/// </summary> /// </summary>
public class IsDebugEnvironmentFilter() : EnvironmentFilter public class IsDebugEnvironmentFilter() : EnvironmentFilter
{ {
/// <summary> /// <summary>
/// Checks if the current environment is debug mode. /// Checks if the current environment is debug mode.
/// </summary> /// </summary>
@@ -42,13 +42,13 @@ namespace Telegrator.Filters
/// <returns>True if the current environment is debug mode; otherwise, false.</returns> /// <returns>True if the current environment is debug mode; otherwise, false.</returns>
public override bool CanPass(FilterExecutionContext<Update> _) public override bool CanPass(FilterExecutionContext<Update> _)
=> IsCurrentEnvDebug; => IsCurrentEnvDebug;
} }
/// <summary> /// <summary>
/// Filter that only passes in release environment builds. /// Filter that only passes in release environment builds.
/// </summary> /// </summary>
public class IsReleaseEnvironmentFilter() : EnvironmentFilter public class IsReleaseEnvironmentFilter() : EnvironmentFilter
{ {
/// <summary> /// <summary>
/// Checks if the current environment is release mode. /// Checks if the current environment is release mode.
/// </summary> /// </summary>
@@ -56,16 +56,16 @@ namespace Telegrator.Filters
/// <returns>True if the current environment is release mode; otherwise, false.</returns> /// <returns>True if the current environment is release mode; otherwise, false.</returns>
public override bool CanPass(FilterExecutionContext<Update> _) public override bool CanPass(FilterExecutionContext<Update> _)
=> !IsCurrentEnvDebug; => !IsCurrentEnvDebug;
} }
/// <summary> /// <summary>
/// Filter that checks environment variable values. /// Filter that checks environment variable values.
/// </summary> /// </summary>
/// <param name="variable">The environment variable name to check.</param> /// <param name="variable">The environment variable name to check.</param>
/// <param name="value">The expected value of the environment variable (optional).</param> /// <param name="value">The expected value of the environment variable (optional).</param>
/// <param name="comparison">The string comparison type to use for value matching.</param> /// <param name="comparison">The string comparison type to use for value matching.</param>
public class EnvironmentVariableFilter(string variable, string? value, StringComparison comparison) : Filter<Update> public class EnvironmentVariableFilter(string variable, string? value, StringComparison comparison) : Filter<Update>
{ {
/// <summary> /// <summary>
/// The environment variable name to check. /// The environment variable name to check.
/// </summary> /// </summary>
@@ -121,5 +121,4 @@ namespace Telegrator.Filters
return envValue.Equals(_value, _comparison); return envValue.Equals(_value, _comparison);
} }
}
} }
+28 -29
View File
@@ -1,13 +1,13 @@
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Base class for filters, providing logical operations and collectability.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class Filter<T> : IFilter<T> where T : class
{ {
/// <summary>
/// Base class for filters, providing logical operations and collectability.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class Filter<T> : IFilter<T> where T : class
{
/// <summary> /// <summary>
/// Creates a filter from a function. /// Creates a filter from a function.
/// </summary> /// </summary>
@@ -81,25 +81,25 @@ namespace Telegrator.Filters
/// </summary> /// </summary>
/// <param name="filter"></param> /// <param name="filter"></param>
public static implicit operator Filter<T>(Func<FilterExecutionContext<T>, bool> filter) => Filter<T>.If(filter); public static implicit operator Filter<T>(Func<FilterExecutionContext<T>, bool> filter) => Filter<T>.If(filter);
} }
/// <summary> /// <summary>
/// A filter that always passes. /// A filter that always passes.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam> /// <typeparam name="T">The type of the input for the filter.</typeparam>
public class AnyFilter<T> : Filter<T> where T : class public class AnyFilter<T> : Filter<T> where T : class
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override bool CanPass(FilterExecutionContext<T> context) public override bool CanPass(FilterExecutionContext<T> context)
=> true; => true;
} }
/// <summary> /// <summary>
/// A filter that inverts the result of another filter. /// A filter that inverts the result of another filter.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam> /// <typeparam name="T">The type of the input for the filter.</typeparam>
public class ReverseFilter<T> : Filter<T> where T : class public class ReverseFilter<T> : Filter<T> where T : class
{ {
private readonly IFilter<T> filter; private readonly IFilter<T> filter;
/// <summary> /// <summary>
@@ -112,14 +112,14 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
public override bool CanPass(FilterExecutionContext<T> context) public override bool CanPass(FilterExecutionContext<T> context)
=> !filter.CanPass(context); => !filter.CanPass(context);
} }
/// <summary> /// <summary>
/// A filter that uses a function to determine if it passes. /// A filter that uses a function to determine if it passes.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam> /// <typeparam name="T">The type of the input for the filter.</typeparam>
public class FunctionFilter<T> : Filter<T> where T : class public class FunctionFilter<T> : Filter<T> where T : class
{ {
private readonly Func<FilterExecutionContext<T>, bool>? FilterFunc; private readonly Func<FilterExecutionContext<T>, bool>? FilterFunc;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FunctionFilter{T}"/> class. /// Initializes a new instance of the <see cref="FunctionFilter{T}"/> class.
@@ -131,5 +131,4 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
public override bool CanPass(FilterExecutionContext<T> context) public override bool CanPass(FilterExecutionContext<T> context)
=> context.Input != null && FilterFunc != null && FilterFunc(context); => context.Input != null && FilterFunc != null && FilterFunc(context);
}
} }
+21 -22
View File
@@ -1,25 +1,25 @@
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Base class for filters that join multiple filters together.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class JoinedFilter<T>(params IFilter<T>[] filters) : Filter<T>, IJoinedFilter<T> where T : class
{ {
/// <summary>
/// Base class for filters that join multiple filters together.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class JoinedFilter<T>(params IFilter<T>[] filters) : Filter<T>, IJoinedFilter<T> where T : class
{
/// <summary> /// <summary>
/// Gets the array of joined filters. /// Gets the array of joined filters.
/// </summary> /// </summary>
public IFilter<T>[] Filters { get; } = filters; public IFilter<T>[] Filters { get; } = filters;
} }
/// <summary> /// <summary>
/// A filter that passes only if both joined filters pass. /// A filter that passes only if both joined filters pass.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam> /// <typeparam name="T">The type of the input for the filter.</typeparam>
public class AndFilter<T> : JoinedFilter<T> where T : class public class AndFilter<T> : JoinedFilter<T> where T : class
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AndFilter{T}"/> class. /// Initializes a new instance of the <see cref="AndFilter{T}"/> class.
/// </summary> /// </summary>
@@ -31,14 +31,14 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
public override bool CanPass(FilterExecutionContext<T> context) public override bool CanPass(FilterExecutionContext<T> context)
=> Filters[0].CanPass(context) && Filters[1].CanPass(context); => Filters[0].CanPass(context) && Filters[1].CanPass(context);
} }
/// <summary> /// <summary>
/// A filter that passes if at least one of the joined filters passes. /// A filter that passes if at least one of the joined filters passes.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam> /// <typeparam name="T">The type of the input for the filter.</typeparam>
public class OrFilter<T> : JoinedFilter<T> where T : class public class OrFilter<T> : JoinedFilter<T> where T : class
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="OrFilter{T}"/> class. /// Initializes a new instance of the <see cref="OrFilter{T}"/> class.
/// </summary> /// </summary>
@@ -50,5 +50,4 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
public override bool CanPass(FilterExecutionContext<T> context) public override bool CanPass(FilterExecutionContext<T> context)
=> Filters[0].CanPass(context) || Filters[1].CanPass(context); => Filters[0].CanPass(context) || Filters[1].CanPass(context);
}
} }
+7 -8
View File
@@ -2,14 +2,14 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Filter that checks if a message contains a mention of the bot or a specific user.
/// Requires a <see cref="MessageHasEntityFilter"/> to be applied first to identify mention entities.
/// </summary>
public class MentionedFilter : MessageFilterBase
{ {
/// <summary>
/// Filter that checks if a message contains a mention of the bot or a specific user.
/// Requires a <see cref="MessageHasEntityFilter"/> to be applied first to identify mention entities.
/// </summary>
public class MentionedFilter : MessageFilterBase
{
/// <summary> /// <summary>
/// The username to check for in the mention (null means check for bot's username). /// The username to check for in the mention (null means check for bot's username).
/// </summary> /// </summary>
@@ -60,5 +60,4 @@ namespace Telegrator.Filters
return false; return false;
} }
}
} }
+42 -43
View File
@@ -3,13 +3,13 @@ using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups; using Telegram.Bot.Types.ReplyMarkups;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Base class for filters that operate on the chat of the message being processed.
/// </summary>
public abstract class MessageChatFilter : MessageFilterBase
{ {
/// <summary>
/// Base class for filters that operate on the chat of the message being processed.
/// </summary>
public abstract class MessageChatFilter : MessageFilterBase
{
/// <summary> /// <summary>
/// Gets the chat of the message being processed. /// Gets the chat of the message being processed.
/// </summary> /// </summary>
@@ -28,35 +28,35 @@ namespace Telegrator.Filters
/// <param name="context">The filter execution context for the chat.</param> /// <param name="context">The filter execution context for the chat.</param>
/// <returns>True if the filter passes; otherwise, false.</returns> /// <returns>True if the filter passes; otherwise, false.</returns>
protected abstract bool CanPassNext(FilterExecutionContext<Chat> context); protected abstract bool CanPassNext(FilterExecutionContext<Chat> context);
} }
/// <summary> /// <summary>
/// Filters messages whose chat is a forum. /// Filters messages whose chat is a forum.
/// </summary> /// </summary>
public class MessageChatIsForumFilter : MessageChatFilter public class MessageChatIsForumFilter : MessageChatFilter
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Chat> _) protected override bool CanPassNext(FilterExecutionContext<Chat> _)
=> Chat.IsForum; => Chat.IsForum;
} }
/// <summary> /// <summary>
/// Filters messages whose chat ID matches the specified value. /// Filters messages whose chat ID matches the specified value.
/// </summary> /// </summary>
public class MessageChatIdFilter(long id) : MessageChatFilter public class MessageChatIdFilter(long id) : MessageChatFilter
{ {
private readonly long Id = id; private readonly long Id = id;
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Chat> _) protected override bool CanPassNext(FilterExecutionContext<Chat> _)
=> Chat.Id == Id; => Chat.Id == Id;
} }
/// <summary> /// <summary>
/// Filters messages whose chat type matches the specified value. /// Filters messages whose chat type matches the specified value.
/// </summary> /// </summary>
public class MessageChatTypeFilter : MessageChatFilter public class MessageChatTypeFilter : MessageChatFilter
{ {
private readonly ChatType? Type; private readonly ChatType? Type;
private readonly ChatTypeFlags? Flags; private readonly ChatTypeFlags? Flags;
@@ -98,13 +98,13 @@ namespace Telegrator.Filters
ChatType.Private => ChatTypeFlags.Private, ChatType.Private => ChatTypeFlags.Private,
_ => null _ => null
}; };
} }
/// <summary> /// <summary>
/// Filters messages whose chat title matches the specified value. /// Filters messages whose chat title matches the specified value.
/// </summary> /// </summary>
public class MessageChatTitleFilter : MessageChatFilter public class MessageChatTitleFilter : MessageChatFilter
{ {
private readonly string? Title; private readonly string? Title;
private readonly StringComparison Comparison = StringComparison.InvariantCulture; private readonly StringComparison Comparison = StringComparison.InvariantCulture;
@@ -130,13 +130,13 @@ namespace Telegrator.Filters
return Chat.Title.Equals(Title, Comparison); return Chat.Title.Equals(Title, Comparison);
} }
} }
/// <summary> /// <summary>
/// Filters messages whose chat username matches the specified value. /// Filters messages whose chat username matches the specified value.
/// </summary> /// </summary>
public class MessageChatUsernameFilter : MessageChatFilter public class MessageChatUsernameFilter : MessageChatFilter
{ {
private readonly string? UserName; private readonly string? UserName;
private readonly StringComparison Comparison = StringComparison.InvariantCulture; private readonly StringComparison Comparison = StringComparison.InvariantCulture;
@@ -162,13 +162,13 @@ namespace Telegrator.Filters
return Chat.Username.Equals(UserName, Comparison); return Chat.Username.Equals(UserName, Comparison);
} }
} }
/// <summary> /// <summary>
/// Filters messages whose chat first and/or last name matches the specified values. /// Filters messages whose chat first and/or last name matches the specified values.
/// </summary> /// </summary>
public class MessageChatNameFilter : MessageChatFilter public class MessageChatNameFilter : MessageChatFilter
{ {
private readonly string? FirstName; private readonly string? FirstName;
private readonly string? LastName; private readonly string? LastName;
private readonly StringComparison Comparison = StringComparison.InvariantCulture; private readonly StringComparison Comparison = StringComparison.InvariantCulture;
@@ -216,5 +216,4 @@ namespace Telegrator.Filters
return true; return true;
} }
}
} }
+54 -55
View File
@@ -3,13 +3,13 @@ using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Base abstract class for all filter of <see cref="Message"/> updates
/// </summary>
public abstract class MessageFilterBase : Filter<Message>
{ {
/// <summary>
/// Base abstract class for all filter of <see cref="Message"/> updates
/// </summary>
public abstract class MessageFilterBase : Filter<Message>
{
/// <summary> /// <summary>
/// Target message for filterring /// Target message for filterring
/// </summary> /// </summary>
@@ -42,13 +42,13 @@ namespace Telegrator.Filters
/// <param name="context"></param> /// <param name="context"></param>
/// <returns></returns> /// <returns></returns>
protected abstract bool CanPassNext(FilterExecutionContext<Message> context); protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
} }
/// <summary> /// <summary>
/// Filters messages by their <see cref="MessageType"/>. /// Filters messages by their <see cref="MessageType"/>.
/// </summary> /// </summary>
public class MessageTypeFilter : MessageFilterBase public class MessageTypeFilter : MessageFilterBase
{ {
private readonly MessageType type; private readonly MessageType type;
/// <summary> /// <summary>
@@ -60,53 +60,53 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Target.Type == type; => Target.Type == type;
} }
/// <summary> /// <summary>
/// Filters messages that are automatic forwards. /// Filters messages that are automatic forwards.
/// </summary> /// </summary>
public class IsAutomaticFormwardMessageFilter : MessageFilterBase public class IsAutomaticFormwardMessageFilter : MessageFilterBase
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Target.IsAutomaticForward; => Target.IsAutomaticForward;
} }
/// <summary> /// <summary>
/// Filters messages that are sent from offline. /// Filters messages that are sent from offline.
/// </summary> /// </summary>
public class IsFromOfflineMessageFilter : MessageFilterBase public class IsFromOfflineMessageFilter : MessageFilterBase
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Target.IsFromOffline; => Target.IsFromOffline;
} }
/// <summary> /// <summary>
/// Filters service messages (e.g., chat events). /// Filters service messages (e.g., chat events).
/// </summary> /// </summary>
public class IsServiceMessageMessageFilter : MessageFilterBase public class IsServiceMessageMessageFilter : MessageFilterBase
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Target.IsServiceMessage; => Target.IsServiceMessage;
} }
/// <summary> /// <summary>
/// Filters messages that are topic messages. /// Filters messages that are topic messages.
/// </summary> /// </summary>
public class IsTopicMessageMessageFilter : MessageFilterBase public class IsTopicMessageMessageFilter : MessageFilterBase
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Target.IsTopicMessage; => Target.IsTopicMessage;
} }
/// <summary> /// <summary>
/// Filters messages by dice throw value and optionally by dice type. /// Filters messages by dice throw value and optionally by dice type.
/// </summary> /// </summary>
public class DiceThrowedFilter : MessageFilterBase public class DiceThrowedFilter : MessageFilterBase
{ {
private readonly DiceType Dice; private readonly DiceType Dice;
private readonly int Value; private readonly int Value;
@@ -148,13 +148,13 @@ namespace Telegrator.Filters
DiceType.Casino => "🎰", DiceType.Casino => "🎰",
_ => null _ => null
}; };
} }
/// <summary> /// <summary>
/// Filters messages by matching their text with a regular expression. /// Filters messages by matching their text with a regular expression.
/// </summary> /// </summary>
public class MessageRegexFilter : RegexFilterBase<Message> public class MessageRegexFilter : RegexFilterBase<Message>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="MessageRegexFilter"/> class with a pattern and options. /// Initializes a new instance of the <see cref="MessageRegexFilter"/> class with a pattern and options.
/// </summary> /// </summary>
@@ -169,13 +169,13 @@ namespace Telegrator.Filters
/// <param name="regex">The regex object.</param> /// <param name="regex">The regex object.</param>
public MessageRegexFilter(Regex regex) public MessageRegexFilter(Regex regex)
: base(msg => msg.Text, regex) { } : base(msg => msg.Text, regex) { }
} }
/// <summary> /// <summary>
/// Filters messages that contain a specific entity type, content, offset, or length. /// Filters messages that contain a specific entity type, content, offset, or length.
/// </summary> /// </summary>
public class MessageHasEntityFilter : MessageFilterBase public class MessageHasEntityFilter : MessageFilterBase
{ {
private readonly StringComparison _stringComparison = StringComparison.CurrentCulture; private readonly StringComparison _stringComparison = StringComparison.CurrentCulture;
private readonly MessageEntityType? EntityType; private readonly MessageEntityType? EntityType;
private readonly string? Content; private readonly string? Content;
@@ -271,5 +271,4 @@ namespace Telegrator.Filters
return true; return true;
} }
}
} }
+52 -53
View File
@@ -1,15 +1,55 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Filter that checks if message has appropriate reply chain.
/// DOES NOT SHiFT MESSAGE FILTERS TARGET
/// </summary>
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
public class MessageHasReplyFilter(int replyDepth = 1) : Filter<Message>
{ {
/// <summary> /// <summary>
/// Filter that checks if message has appropriate reply chain. /// Gets the replied message at the specified depth in the reply chain.
/// DOES NOT SHiFT MESSAGE FILTERS TARGET
/// </summary> /// </summary>
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param> public Message Reply { get; private set; } = null!;
public class MessageHasReplyFilter(int replyDepth = 1) : Filter<Message>
/// <summary>
/// Gets the depth of reply chain traversal.
/// </summary>
public int ReplyDepth { get; private set; } = replyDepth;
/// <summary>
/// Determines if the message can pass through the filter by first validating
/// the reply chain and then applying specific filter logic.
/// </summary>
/// <param name="context">The filter execution context containing the message.</param>
/// <returns>True if the message passes both reply validation and specific filter criteria; otherwise, false.</returns>
public override bool CanPass(FilterExecutionContext<Message> context)
{ {
Message reply = context.Input;
for (int i = ReplyDepth; i > 0; i--)
{
if (reply.ReplyToMessage is not { Id: > 0 } replyMessage)
return false;
reply = replyMessage;
}
Reply = reply;
return true;
}
}
/// <summary>
/// Helper filter class for filters that operate on replied messages.
/// Provides functionality to traverse reply chains and access replied message content
/// and shifts any next message filter to filter the content of found reply.
/// </summary>
/// <param name="replyDepth"></param>
public class FromReplyChainFilter(int replyDepth = 1) : Filter<Message>
{
/// <summary> /// <summary>
/// Gets the replied message at the specified depth in the reply chain. /// Gets the replied message at the specified depth in the reply chain.
/// </summary> /// </summary>
@@ -40,54 +80,14 @@ namespace Telegrator.Filters
Reply = reply; Reply = reply;
return true; return true;
} }
} }
/// <summary> /// <summary>
/// Helper filter class for filters that operate on replied messages. /// Filter that checks if the replied message was sent by the bot itself.
/// Provides functionality to traverse reply chains and access replied message content /// <para>( ! ): REQUIRES <see cref="MessageHasReplyFilter"/> before</para>
/// and shifts any next message filter to filter the content of found reply. /// </summary>
/// </summary> public class MeRepliedFilter : Filter<Message>
/// <param name="replyDepth"></param> {
public class FromReplyChainFilter(int replyDepth = 1) : Filter<Message>
{
/// <summary>
/// Gets the replied message at the specified depth in the reply chain.
/// </summary>
public Message Reply { get; private set; } = null!;
/// <summary>
/// Gets the depth of reply chain traversal.
/// </summary>
public int ReplyDepth { get; private set; } = replyDepth;
/// <summary>
/// Determines if the message can pass through the filter by first validating
/// the reply chain and then applying specific filter logic.
/// </summary>
/// <param name="context">The filter execution context containing the message.</param>
/// <returns>True if the message passes both reply validation and specific filter criteria; otherwise, false.</returns>
public override bool CanPass(FilterExecutionContext<Message> context)
{
Message reply = context.Input;
for (int i = ReplyDepth; i > 0; i--)
{
if (reply.ReplyToMessage is not { Id: > 0 } replyMessage)
return false;
reply = replyMessage;
}
Reply = reply;
return true;
}
}
/// <summary>
/// Filter that checks if the replied message was sent by the bot itself.
/// <para>( ! ): REQUIRES <see cref="MessageHasReplyFilter"/> before</para>
/// </summary>
public class MeRepliedFilter : Filter<Message>
{
/// <summary> /// <summary>
/// Checks if the replied message was sent by the bot. /// Checks if the replied message was sent by the bot.
/// </summary> /// </summary>
@@ -98,5 +98,4 @@ namespace Telegrator.Filters
MessageHasReplyFilter repliedFilter = context.CompletedFilters.Get<MessageHasReplyFilter>(0); MessageHasReplyFilter repliedFilter = context.CompletedFilters.Get<MessageHasReplyFilter>(0);
return context.BotInfo.User == repliedFilter.Reply.From; return context.BotInfo.User == repliedFilter.Reply.From;
} }
}
} }
+42 -43
View File
@@ -1,14 +1,14 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Abstract base class for filters that operate on message senders.
/// Provides functionality to access and validate the user who sent the message.
/// </summary>
public abstract class MessageSenderFilter : MessageFilterBase
{ {
/// <summary>
/// Abstract base class for filters that operate on message senders.
/// Provides functionality to access and validate the user who sent the message.
/// </summary>
public abstract class MessageSenderFilter : MessageFilterBase
{
/// <summary> /// <summary>
/// Gets the user who sent the message. /// Gets the user who sent the message.
/// </summary> /// </summary>
@@ -31,14 +31,14 @@ namespace Telegrator.Filters
return CanPassNext(context); return CanPassNext(context);
} }
} }
/// <summary> /// <summary>
/// Filter that checks if the message sender has a specific username. /// Filter that checks if the message sender has a specific username.
/// </summary> /// </summary>
/// <param name="username">The username to check for.</param> /// <param name="username">The username to check for.</param>
public class FromUsernameFilter(string username) : MessageSenderFilter public class FromUsernameFilter(string username) : MessageSenderFilter
{ {
/// <summary> /// <summary>
/// The username to check for. /// The username to check for.
/// </summary> /// </summary>
@@ -64,16 +64,16 @@ namespace Telegrator.Filters
/// <returns>True if the sender has the specified username; otherwise, false.</returns> /// <returns>True if the sender has the specified username; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> User.Username != null && User.Username.Equals(_username, _comparison); => User.Username != null && User.Username.Equals(_username, _comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if the message sender has specific first and/or last name. /// Filter that checks if the message sender has specific first and/or last name.
/// </summary> /// </summary>
/// <param name="firstName">The first name to check for.</param> /// <param name="firstName">The first name to check for.</param>
/// <param name="lastName">The last name to check for (optional).</param> /// <param name="lastName">The last name to check for (optional).</param>
/// <param name="comparison">The string comparison type to use.</param> /// <param name="comparison">The string comparison type to use.</param>
public class FromUserFilter(string firstName, string? lastName, StringComparison comparison) : MessageSenderFilter public class FromUserFilter(string firstName, string? lastName, StringComparison comparison) : MessageSenderFilter
{ {
/// <summary> /// <summary>
/// The first name to check for. /// The first name to check for.
/// </summary> /// </summary>
@@ -130,14 +130,14 @@ namespace Telegrator.Filters
return User.FirstName.Equals(_firstName, _comparison); return User.FirstName.Equals(_firstName, _comparison);
} }
} }
/// <summary> /// <summary>
/// Filter that checks if the message sender has a specific user ID. /// Filter that checks if the message sender has a specific user ID.
/// </summary> /// </summary>
/// <param name="userId">The user ID to check for.</param> /// <param name="userId">The user ID to check for.</param>
public class FromUserIdFilter(long userId) : MessageSenderFilter public class FromUserIdFilter(long userId) : MessageSenderFilter
{ {
/// <summary> /// <summary>
/// The user ID to check for. /// The user ID to check for.
/// </summary> /// </summary>
@@ -150,13 +150,13 @@ namespace Telegrator.Filters
/// <returns>True if the sender has the specified user ID; otherwise, false.</returns> /// <returns>True if the sender has the specified user ID; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> User.Id == _userId; => User.Id == _userId;
} }
/// <summary> /// <summary>
/// Filter that checks if the message was sent by a bot. /// Filter that checks if the message was sent by a bot.
/// </summary> /// </summary>
public class FromBotFilter() : MessageSenderFilter public class FromBotFilter() : MessageSenderFilter
{ {
/// <summary> /// <summary>
/// Checks if the message was sent by a bot. /// Checks if the message was sent by a bot.
/// </summary> /// </summary>
@@ -164,13 +164,13 @@ namespace Telegrator.Filters
/// <returns>True if the message was sent by a bot; otherwise, false.</returns> /// <returns>True if the message was sent by a bot; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> User.IsBot; => User.IsBot;
} }
/// <summary> /// <summary>
/// Filter that checks if the message was sent by a premium user. /// Filter that checks if the message was sent by a premium user.
/// </summary> /// </summary>
public class FromPremiumUserFilter() : MessageSenderFilter public class FromPremiumUserFilter() : MessageSenderFilter
{ {
/// <summary> /// <summary>
/// Checks if the message was sent by a premium user. /// Checks if the message was sent by a premium user.
/// </summary> /// </summary>
@@ -178,5 +178,4 @@ namespace Telegrator.Filters
/// <returns>True if the message was sent by a premium user; otherwise, false.</returns> /// <returns>True if the message was sent by a premium user; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> User.IsPremium; => User.IsPremium;
}
} }
+52 -54
View File
@@ -1,15 +1,14 @@
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using static System.Net.Mime.MediaTypeNames;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Abstract base class for filters that operate on message text content.
/// Provides common functionality for extracting and validating message text.
/// </summary>
public abstract class MessageTextFilter : MessageFilterBase
{ {
/// <summary>
/// Abstract base class for filters that operate on message text content.
/// Provides common functionality for extracting and validating message text.
/// </summary>
public abstract class MessageTextFilter : MessageFilterBase
{
/// <summary> /// <summary>
/// Gets the current message being processed by the filter. /// Gets the current message being processed by the filter.
/// </summary> /// </summary>
@@ -37,15 +36,15 @@ namespace Telegrator.Filters
Text = Target.Text; Text = Target.Text;
return CanPassNext(context); return CanPassNext(context);
} }
} }
/// <summary> /// <summary>
/// Filter that checks if the message text starts with a specified content. /// Filter that checks if the message text starts with a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the message text starts with.</param> /// <param name="content">The content to check if the message text starts with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
public class TextStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter public class TextStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter
{ {
/// <summary> /// <summary>
/// The content to check if the message text starts with. /// The content to check if the message text starts with.
/// </summary> /// </summary>
@@ -63,15 +62,15 @@ namespace Telegrator.Filters
/// <returns>True if the text starts with the specified content; otherwise, false.</returns> /// <returns>True if the text starts with the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Text.StartsWith(Content, Comparison); => Text.StartsWith(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if the message text ends with a specified content. /// Filter that checks if the message text ends with a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the message text ends with.</param> /// <param name="content">The content to check if the message text ends with.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
public class TextEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter public class TextEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter
{ {
/// <summary> /// <summary>
/// The content to check if the message text ends with. /// The content to check if the message text ends with.
/// </summary> /// </summary>
@@ -89,15 +88,15 @@ namespace Telegrator.Filters
/// <returns>True if the text ends with the specified content; otherwise, false.</returns> /// <returns>True if the text ends with the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Text.EndsWith(Content, Comparison); => Text.EndsWith(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if the message text contains a specified content. /// Filter that checks if the message text contains a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the message text contains.</param> /// <param name="content">The content to check if the message text contains.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
public class TextContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter public class TextContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter
{ {
/// <summary> /// <summary>
/// The content to check if the message text contains. /// The content to check if the message text contains.
/// </summary> /// </summary>
@@ -115,15 +114,15 @@ namespace Telegrator.Filters
/// <returns>True if the text contains the specified content; otherwise, false.</returns> /// <returns>True if the text contains the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Text.IndexOf(Content, Comparison) >= 0; => Text.IndexOf(Content, Comparison) >= 0;
} }
/// <summary> /// <summary>
/// Filter that checks if the message text equals a specified content. /// Filter that checks if the message text equals a specified content.
/// </summary> /// </summary>
/// <param name="content">The content to check if the message text equals.</param> /// <param name="content">The content to check if the message text equals.</param>
/// <param name="comparison">The string comparison type to use for the check.</param> /// <param name="comparison">The string comparison type to use for the check.</param>
public class TextEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter public class TextEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture) : MessageTextFilter
{ {
/// <summary> /// <summary>
/// The content to check if the message text equals. /// The content to check if the message text equals.
/// </summary> /// </summary>
@@ -141,13 +140,13 @@ namespace Telegrator.Filters
/// <returns>True if the text equals the specified content; otherwise, false.</returns> /// <returns>True if the text equals the specified content; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> Text.Equals(Content, Comparison); => Text.Equals(Content, Comparison);
} }
/// <summary> /// <summary>
/// Filter that checks if the message text is not null or empty. /// Filter that checks if the message text is not null or empty.
/// </summary> /// </summary>
public class TextNotNullOrEmptyFilter() : MessageTextFilter public class TextNotNullOrEmptyFilter() : MessageTextFilter
{ {
/// <summary> /// <summary>
/// Checks if the message text is not null or empty. /// Checks if the message text is not null or empty.
/// </summary> /// </summary>
@@ -155,14 +154,14 @@ namespace Telegrator.Filters
/// <returns>True if the text is not null or empty; otherwise, false.</returns> /// <returns>True if the text is not null or empty; otherwise, false.</returns>
protected override bool CanPassNext(FilterExecutionContext<Message> _) protected override bool CanPassNext(FilterExecutionContext<Message> _)
=> !string.IsNullOrEmpty(Text); => !string.IsNullOrEmpty(Text);
} }
/// <summary> /// <summary>
/// Filter that checks if the message text contains a 'word'. /// Filter that checks if the message text contains a 'word'.
/// 'Word' must be a separate member of the text, and not have any alphabetic characters next to it. /// 'Word' must be a separate member of the text, and not have any alphabetic characters next to it.
/// </summary> /// </summary>
public class TextContainsWordFilter(string word, StringComparison comparison = StringComparison.InvariantCulture, int startIndex = 0) : MessageTextFilter public class TextContainsWordFilter(string word, StringComparison comparison = StringComparison.InvariantCulture, int startIndex = 0) : MessageTextFilter
{ {
/// <summary> /// <summary>
/// The content to check if the message text equals. /// The content to check if the message text equals.
/// </summary> /// </summary>
@@ -181,5 +180,4 @@ namespace Telegrator.Filters
/// <inheritdoc/> /// <inheritdoc/>
protected override bool CanPassNext(FilterExecutionContext<Message> context) protected override bool CanPassNext(FilterExecutionContext<Message> context)
=> Text.ContainsWord(Word, Comparison, StartIndex); => Text.ContainsWord(Word, Comparison, StartIndex);
}
} }
+7 -8
View File
@@ -1,14 +1,14 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
namespace Telegrator.Filters namespace Telegrator.Filters;
/// <summary>
/// Base class for filters that use regular expressions to match text in updates.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class RegexFilterBase<T> : Filter<T> where T : class
{ {
/// <summary>
/// Base class for filters that use regular expressions to match text in updates.
/// </summary>
/// <typeparam name="T">The type of the input for the filter.</typeparam>
public abstract class RegexFilterBase<T> : Filter<T> where T : class
{
private readonly Func<T, string?> getString; private readonly Func<T, string?> getString;
private readonly Regex regex; private readonly Regex regex;
@@ -54,5 +54,4 @@ namespace Telegrator.Filters
Matches = regex.Matches(text); Matches = regex.Matches(text);
return Matches.Count > 0; return Matches.Count > 0;
} }
}
} }
+9 -10
View File
@@ -2,17 +2,17 @@
using Telegrator.Core.Filters; using Telegrator.Core.Filters;
using Telegrator.Core.States; using Telegrator.Core.States;
namespace Telegrator.Filters namespace Telegrator.Filters;
{
/// <summary> /// <summary>
/// Filters updates by comparing a resolved state key with a target key. /// Filters updates by comparing a resolved state key with a target key.
/// </summary> /// </summary>
/// <typeparam name="TKey">The type of the key resolver used to get state key.</typeparam> /// <typeparam name="TKey">The type of the key resolver used to get state key.</typeparam>
/// <typeparam name="TValue">The type of the key used for state resolution.</typeparam> /// <typeparam name="TValue">The type of the key used for state resolution.</typeparam>
public class StateKeyFilter<TKey, TValue> : Filter<Update> public class StateKeyFilter<TKey, TValue> : Filter<Update>
where TKey : IStateKeyResolver, new() where TKey : IStateKeyResolver, new()
where TValue : IEquatable<TValue> where TValue : IEquatable<TValue>
{ {
private readonly TValue? TargetKey; private readonly TValue? TargetKey;
/// <summary> /// <summary>
@@ -40,5 +40,4 @@ namespace Telegrator.Filters
return TargetKey.Equals(value); return TargetKey.Equals(value);
} }
}
} }
+1
View File
@@ -8,3 +8,4 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0290")] [assembly: SuppressMessage("Style", "IDE0290")]
[assembly: SuppressMessage("Style", "IDE0090")] [assembly: SuppressMessage("Style", "IDE0090")]
[assembly: SuppressMessage("Style", "IDE0057")] [assembly: SuppressMessage("Style", "IDE0057")]
[assembly: SuppressMessage("Style", "IDE0270")]

Some files were not shown because too many files have changed in this diff Show More