-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: scheduled event recurrency rules
- Loading branch information
Showing
11 changed files
with
372 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
DisCatSharp/Entities/Guild/ScheduledEvent/DiscordRecurrenceRuleNWeekday.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using DisCatSharp.Enums; | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace DisCatSharp.Entities; | ||
|
||
/// <summary> | ||
/// Represents a specific day within a specific week to recur on. | ||
/// </summary> | ||
public sealed class DiscordRecurrenceRuleNWeekday | ||
{ | ||
/// <summary> | ||
/// Gets or sets the week number (1-5) for recurrence. | ||
/// </summary> | ||
[JsonProperty("n")] | ||
public int WeekNumber { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the day of the week for recurrence. | ||
/// </summary> | ||
[JsonProperty("day")] | ||
public RecurrenceRuleWeekday Day { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEventRecurrenceRule.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
using DisCatSharp.Enums; | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace DisCatSharp.Entities; | ||
|
||
/// <summary> | ||
/// Represents the recurrence rule for a scheduled event. | ||
/// </summary> | ||
public sealed class DiscordScheduledEventRecurrenceRule | ||
{ | ||
/// <summary> | ||
/// Gets or sets the start time of the recurrence interval. | ||
/// </summary> | ||
[JsonProperty("start")] | ||
public DateTimeOffset Start { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the end time of the recurrence interval. | ||
/// </summary> | ||
[JsonProperty("end")] | ||
public DateTimeOffset? End { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the frequency of the recurrence. | ||
/// </summary> | ||
[JsonProperty("frequency")] | ||
public RecurrenceRuleFrequency Frequency { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the interval between events. | ||
/// </summary> | ||
[JsonProperty("interval")] | ||
public int Interval { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets specific days within a week for the event to recur on. | ||
/// </summary> | ||
[JsonProperty("by_weekday", NullValueHandling = NullValueHandling.Include)] | ||
public List<RecurrenceRuleWeekday>? ByWeekday { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets specific days within a specific week (1-5) to recur on. | ||
/// </summary> | ||
[JsonProperty("by_n_weekday", NullValueHandling = NullValueHandling.Include)] | ||
public List<DiscordRecurrenceRuleNWeekday>? ByNWeekday { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets specific months to recur on. | ||
/// </summary> | ||
[JsonProperty("by_month", NullValueHandling = NullValueHandling.Include)] | ||
public List<int>? ByMonth { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets specific dates within a month to recur on. | ||
/// </summary> | ||
[JsonProperty("by_month_day", NullValueHandling = NullValueHandling.Include)] | ||
public List<int>? ByMonthDay { get; set; } | ||
|
||
/// <summary> | ||
/// Gets specific dates within a year to recur on. | ||
/// </summary> | ||
[JsonProperty("by_year_day", NullValueHandling = NullValueHandling.Include)] | ||
public List<int>? ByYearDay { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets the total amount of times that the event is allowed to recur before stopping. | ||
/// </summary> | ||
[JsonProperty("count", NullValueHandling = NullValueHandling.Include)] | ||
public int? Count { get; internal set; } | ||
} |
96 changes: 96 additions & 0 deletions
96
DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEventRecurrenceRuleValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
using DisCatSharp.Enums; | ||
|
||
namespace DisCatSharp.Entities; | ||
|
||
/// <summary> | ||
/// Validator for <see cref="DiscordScheduledEventRecurrenceRule" /> instances. | ||
/// </summary> | ||
public static class DiscordScheduledEventRecurrenceRuleValidator | ||
{ | ||
/// <summary> | ||
/// A collection of valid weekday sets for events with a daily recurrence frequency. | ||
/// </summary> | ||
private static readonly List<List<RecurrenceRuleWeekday>> s_validDailyWeekdaySets = [CreateWeekdaySet(RecurrenceRuleWeekday.Monday, RecurrenceRuleWeekday.Tuesday, RecurrenceRuleWeekday.Wednesday, RecurrenceRuleWeekday.Thursday, RecurrenceRuleWeekday.Friday), CreateWeekdaySet(RecurrenceRuleWeekday.Tuesday, RecurrenceRuleWeekday.Wednesday, RecurrenceRuleWeekday.Thursday, RecurrenceRuleWeekday.Friday, RecurrenceRuleWeekday.Saturday), CreateWeekdaySet(RecurrenceRuleWeekday.Sunday, RecurrenceRuleWeekday.Monday, RecurrenceRuleWeekday.Tuesday, RecurrenceRuleWeekday.Wednesday, RecurrenceRuleWeekday.Thursday), CreateWeekdaySet(RecurrenceRuleWeekday.Friday, RecurrenceRuleWeekday.Saturday), CreateWeekdaySet(RecurrenceRuleWeekday.Saturday, RecurrenceRuleWeekday.Sunday), CreateWeekdaySet(RecurrenceRuleWeekday.Sunday, RecurrenceRuleWeekday.Monday)]; | ||
|
||
/// <summary> | ||
/// Creates a set of weekdays for easier readability. | ||
/// </summary> | ||
/// <param name="weekdays">The weekdays to include in the set.</param> | ||
/// <returns>A list of <see cref="RecurrenceRuleWeekday" /> objects.</returns> | ||
private static List<RecurrenceRuleWeekday> CreateWeekdaySet(params RecurrenceRuleWeekday[] weekdays) | ||
=> [..weekdays]; | ||
|
||
/// <summary> | ||
/// Validates the recurrence rule. | ||
/// </summary> | ||
/// <param name="rule">The recurrence rule to validate.</param> | ||
/// <returns>A tuple containing a boolean indicating validity and an optional error message.</returns> | ||
public static (bool IsValid, string? ErrorMessage) Validate(this DiscordScheduledEventRecurrenceRule rule) | ||
{ | ||
return rule.ByWeekday is not null && rule.ByNWeekday is not null | ||
? ((bool IsValid, string? ErrorMessage))(false, "by_weekday and by_n_weekday cannot both be set.") | ||
: rule.ByMonth is not null && rule.ByMonthDay is not null | ||
? ((bool IsValid, string? ErrorMessage))(false, "by_month and by_month_day cannot both be set.") | ||
: rule.Frequency switch | ||
{ | ||
RecurrenceRuleFrequency.Daily => rule.ValidateDailyFrequency(), | ||
RecurrenceRuleFrequency.Weekly => rule.ValidateWeeklyFrequency(), | ||
RecurrenceRuleFrequency.Monthly => rule.ValidateMonthlyFrequency(), | ||
RecurrenceRuleFrequency.Yearly => rule.ValidateYearlyFrequency(), | ||
_ => (false, "Unknown frequency type.") | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// Validates recurrence rules with a daily frequency. | ||
/// </summary> | ||
/// <param name="rule">The recurrence rule to validate.</param> | ||
/// <returns>A tuple containing a boolean indicating validity and an optional error message.</returns> | ||
private static (bool IsValid, string? ErrorMessage) ValidateDailyFrequency(this DiscordScheduledEventRecurrenceRule rule) | ||
=> rule.ByWeekday is not null && !rule.ByWeekday.IsValidDailyWeekdaySet() | ||
? ((bool IsValid, string? ErrorMessage))(false, "Invalid by_weekday set for daily frequency.") | ||
: (true, null); | ||
|
||
/// <summary> | ||
/// Validates recurrence rules with a weekly frequency. | ||
/// </summary> | ||
/// <param name="rule">The recurrence rule to validate.</param> | ||
/// <returns>A tuple containing a boolean indicating validity and an optional error message.</returns> | ||
private static (bool IsValid, string? ErrorMessage) ValidateWeeklyFrequency(this DiscordScheduledEventRecurrenceRule rule) | ||
=> rule.ByWeekday?.Count is not 1 | ||
? ((bool IsValid, string? ErrorMessage))(false, "Weekly events must have a single day set in by_weekday.") | ||
: rule.Interval is not 1 and not 2 | ||
? ((bool IsValid, string? ErrorMessage))(false, "Weekly events can only have an interval of 1 or 2.") | ||
: (true, null); | ||
|
||
/// <summary> | ||
/// Validates recurrence rules with a monthly frequency. | ||
/// </summary> | ||
/// <param name="rule">The recurrence rule to validate.</param> | ||
/// <returns>A tuple containing a boolean indicating validity and an optional error message.</returns> | ||
private static (bool IsValid, string? ErrorMessage) ValidateMonthlyFrequency(this DiscordScheduledEventRecurrenceRule rule) | ||
=> rule.ByNWeekday?.Count is not 1 | ||
? ((bool IsValid, string? ErrorMessage))(false, "Monthly events must have a single day set in by_n_weekday.") | ||
: (true, null); | ||
|
||
/// <summary> | ||
/// Validates recurrence rules with a yearly frequency. | ||
/// </summary> | ||
/// <param name="rule">The recurrence rule to validate.</param> | ||
/// <returns>A tuple containing a boolean indicating validity and an optional error message.</returns> | ||
private static (bool IsValid, string? ErrorMessage) ValidateYearlyFrequency(this DiscordScheduledEventRecurrenceRule rule) | ||
=> rule.ByMonth?.Count is not 1 || rule.ByMonthDay?.Count is not 1 | ||
? ((bool IsValid, string? ErrorMessage))(false, "Yearly events must have both by_month and by_month_day set to a single value.") | ||
: (true, null); | ||
|
||
/// <summary> | ||
/// Validates if the weekday set is valid for a daily frequency. | ||
/// </summary> | ||
/// <param name="byWeekday">The weekday set to validate.</param> | ||
/// <returns><see langword="true" /> if the set is valid; otherwise, <see langword="false" />.</returns> | ||
private static bool IsValidDailyWeekdaySet(this IReadOnlyCollection<RecurrenceRuleWeekday> byWeekday) | ||
=> s_validDailyWeekdaySets.Any(set => set.SequenceEqual(byWeekday)); | ||
} |
27 changes: 27 additions & 0 deletions
27
DisCatSharp/Enums/Guild/ScheduledEvent/RecurrenceRuleFrequency.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
namespace DisCatSharp.Enums; | ||
|
||
/// <summary> | ||
/// Represents the frequency of a scheduled event's recurrence. | ||
/// </summary> | ||
public enum RecurrenceRuleFrequency | ||
{ | ||
/// <summary> | ||
/// The scheduled event repeats yearly. | ||
/// </summary> | ||
Yearly = 0, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats monthly. | ||
/// </summary> | ||
Monthly = 1, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats weekly. | ||
/// </summary> | ||
Weekly = 2, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats daily. | ||
/// </summary> | ||
Daily = 3 | ||
} |
42 changes: 42 additions & 0 deletions
42
DisCatSharp/Enums/Guild/ScheduledEvent/RecurrenceRuleWeekday.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
namespace DisCatSharp.Enums; | ||
|
||
/// <summary> | ||
/// Represents the days of the week for scheduling recurrent events. | ||
/// </summary> | ||
public enum RecurrenceRuleWeekday | ||
{ | ||
/// <summary> | ||
/// The scheduled event repeats on mondays. | ||
/// </summary> | ||
Monday = 0, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats tuesdays. | ||
/// </summary> | ||
Tuesday = 1, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats wednesdays. | ||
/// </summary> | ||
Wednesday = 2, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats thursdays. | ||
/// </summary> | ||
Thursday = 3, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats fridays. | ||
/// </summary> | ||
Friday = 4, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats saturdays. | ||
/// </summary> | ||
Saturday = 5, | ||
|
||
/// <summary> | ||
/// The scheduled event repeats sundays. | ||
/// </summary> | ||
Sunday = 6 | ||
} |
Oops, something went wrong.