diff --git a/Telegrator/Annotations/CommandArgumentAttributes.cs b/Telegrator/Annotations/CommandArgumentAttributes.cs
index ceac359..cff75c0 100644
--- a/Telegrator/Annotations/CommandArgumentAttributes.cs
+++ b/Telegrator/Annotations/CommandArgumentAttributes.cs
@@ -3,6 +3,10 @@ using Telegrator.Filters;
namespace Telegrator.Annotations
{
+ public class ArgumentCountAttribute(int count)
+ : MessageFilterAttribute(new ArgumentCountFilter(count))
+ { }
+
///
/// Attribute for filtering messages where a command argument starts with the specified content.
///
@@ -50,7 +54,7 @@ namespace Telegrator.Annotations
/// The regex options to use for the pattern matching.
/// The timeout for the regex match operation.
/// The index of the argument to check (0-based).
- public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, TimeSpan matchTimeout = default, int index = 0)
- : MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, matchTimeout, index))
+ public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, int index = 0)
+ : MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, index: index))
{ }
}
diff --git a/Telegrator/Filters/CommandArgumentFilter.cs b/Telegrator/Filters/CommandArgumentFilter.cs
index 13ef094..c41b4f8 100644
--- a/Telegrator/Filters/CommandArgumentFilter.cs
+++ b/Telegrator/Filters/CommandArgumentFilter.cs
@@ -42,6 +42,18 @@ namespace Telegrator.Filters
protected abstract bool CanPassNext(FilterExecutionContext context);
}
+ public class ArgumentCountFilter(int count) : Filter
+ {
+ private readonly int Count = count;
+
+ public override bool CanPass(FilterExecutionContext context)
+ {
+ CommandHandlerAttribute attr = context.CompletedFilters.Get(0);
+ string[] args = attr.Arguments ??= context.Input.SplitArgs();
+ return args.Length >= Count;
+ }
+ }
+
///
/// Filter that checks if a command argument starts with a specified content.
///
diff --git a/Telegrator/Handlers/Components/FiltersFallbackReport.cs b/Telegrator/Handlers/Components/FiltersFallbackReport.cs
index b1fb1db..fb1b9f7 100644
--- a/Telegrator/Handlers/Components/FiltersFallbackReport.cs
+++ b/Telegrator/Handlers/Components/FiltersFallbackReport.cs
@@ -38,27 +38,53 @@ namespace Telegrator.Handlers.Components
///
public List UpdateFilters { get; } = [];
+ public bool Only(string name, int index = 0)
+ {
+ FilterFallbackInfo? info = UpdateFilters.SingleSafe(info => info.Failed);
+ if (info != null && info.Name != name)
+ return false;
+
+ FilterFallbackInfo? target = UpdateFilters.ElementAtOrDefault(index);
+ return ReferenceEquals(target, info);
+ }
+
+ public bool Only(string[] names)
+ {
+ return UpdateFilters
+ .Where(info => info.Failed)
+ .Select(info => info.Name)
+ .SequenceEqual(names);
+ }
+
+ public bool Except(string name, int index = 0)
+ {
+ FilterFallbackInfo? info = UpdateFilters.SingleSafe(info => !info.Failed);
+ if (info != null && info.Name != name)
+ return false;
+
+ FilterFallbackInfo? target = UpdateFilters.ElementAtOrDefault(index);
+ return ReferenceEquals(target, info);
+ }
+
+ public bool Except(string[] names)
+ {
+ return UpdateFilters
+ .Where(info => !info.Failed)
+ .Select(info => info.Name)
+ .SequenceEqual(names);
+ }
+
+ public bool ExceptAttribute(int index = 0) where T : UpdateFilterAttributeBase
+ => Except(nameof(T), index);
+
///
/// Checks if the failure is due to a specific attribute type, excluding other failures.
///
/// The attribute type to check for.
/// The index of the filter to check (default: 0).
/// True if the failure is exclusively due to the specified attribute type; otherwise, false.
- public bool ExceptAttribute(int index = 0) where T : UpdateFilterAttributeBase
- {
- string name = typeof(T).Name;
-
- IEnumerable failed = UpdateFilters.Where(info => info.Failed);
- if (failed.Count() != 1)
- return false;
-
- FilterFallbackInfo info = failed.ElementAt(0);
- if (info.Name != name)
- return false;
-
- FilterFallbackInfo? target = UpdateFilters.ElementAtOrDefault(index);
- return target == info;
- }
+ public bool OnlyAttribute(int index = 0) where T : UpdateFilterAttributeBase
+ => Only(nameof(T), index);
}
///
diff --git a/Telegrator/Providers/HandlersCollection.cs b/Telegrator/Providers/HandlersCollection.cs
index d58ef53..37c4f4b 100644
--- a/Telegrator/Providers/HandlersCollection.cs
+++ b/Telegrator/Providers/HandlersCollection.cs
@@ -3,7 +3,6 @@ using Telegram.Bot.Types.Enums;
using Telegrator.Annotations;
using Telegrator.Attributes;
using Telegrator.Configuration;
-using Telegrator.Handlers.Components;
using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors;
diff --git a/Telegrator/TypesExtensions.cs b/Telegrator/TypesExtensions.cs
index 3acf39c..6d2c885 100644
--- a/Telegrator/TypesExtensions.cs
+++ b/Telegrator/TypesExtensions.cs
@@ -1,4 +1,5 @@
-using System.Collections.ObjectModel;
+using System;
+using System.Collections.ObjectModel;
using System.Reflection;
using Telegram.Bot;
using Telegram.Bot.Types;
@@ -643,9 +644,6 @@ namespace Telegrator
if (handlerType.IsCustomDescriptorsProvider())
{
- if (!handlerType.HasParameterlessCtor())
- throw new Exception();
-
ICustomDescriptorsProvider provider = (ICustomDescriptorsProvider)Activator.CreateInstance(handlerType);
foreach (HandlerDescriptor handlerDescriptor in provider.DescribeHandlers())
handlers.AddDescriptor(handlerDescriptor);
@@ -944,23 +942,6 @@ namespace Telegrator
return source;
}
- /* Found built in method :_(
- ///
- /// Creates a new with the elements of the that were successfully cast to the
- ///
- ///
- ///
- ///
- public static IEnumerable WhereCast(this IEnumerable source)
- {
- foreach (object value in source)
- {
- if (value is TResult result)
- yield return result;
- }
- }
- */
-
///
/// Sets the value of a key in a dictionary, or if the key does not exist, adds it
///
@@ -1027,6 +1008,32 @@ namespace Telegrator
list.Add(item);
}
}
+
+ public static int IndexOf(this IEnumerable source, Func predicate)
+ {
+ int index = 0;
+ foreach (T item in source)
+ {
+ if (predicate.Invoke(item))
+ return index;
+
+ index++;
+ }
+
+ return -1;
+ }
+
+ public static IEnumerable Repeat(this T item, int times)
+ => Enumerable.Range(0, times).Select(_ => item);
+
+ public static T? SingleSafe(this IEnumerable source)
+ => source.Count() == 1 ? source.ElementAt(0) : default;
+
+ public static T? SingleSafe(this IEnumerable source, Func predicate)
+ {
+ source = source.Where(predicate);
+ return source.Count() == 1 ? source.ElementAt(0) : default;
+ }
}
///
@@ -1190,6 +1197,22 @@ namespace Telegrator
yield return chunk.ToString();
}
}
+
+ public static string FirstLetterToUpper(this string target)
+ {
+ char[] chars = target.ToCharArray();
+ int index = chars.IndexOf(char.IsLetter);
+ chars[index] = char.ToUpper(chars[index]);
+ return new string(chars);
+ }
+
+ public static string FirstLetterToLower(this string target)
+ {
+ char[] chars = target.ToCharArray();
+ int index = chars.IndexOf(char.IsLetter);
+ chars[index] = char.ToLower(chars[index]);
+ return new string(chars);
+ }
}
///