[API Revision] Adding properties to `Calendar.RecurrenceRule.End`

Hi all,

I would like to propose adding a few properties to Calendar.RecurrenceRule.End, first introduced in SF-0009

Extending Calendar.RecurrenceRule.End

Revision history

  • v1 Initial version

Introduction

In SF-0009 we introduced Calendar.RecurrenceRule. In this API, we represent the end of a recurrence rule with the struct Calendar.RecurrenceRule.End:

/// When a recurring event stops recurring
public struct End: Sendable, Equatable {
    /// The event stops repeating after a given number of times
    /// - Parameter count: how many times to repeat the event, including
    ///                    the first occurrence. `count` must be greater
    ///                    than `0`
    public static func afterOccurrences(_ count: Int) -> Self
    /// The event stops repeating after a given date
    /// - Parameter date: the date on which the event may last occur. No
    ///                   further occurrences will be found after that
    public static func afterDate(_ date: Date) -> Self
    /// The event repeats indefinitely
    public static var never: Self

}

This is de-facto an enum that was declared as struct to be future-proof. However, the original API only allowed construction of the recurrence rule end, and did not allow any introspection afterwards. This proposal adds a few properties to Calendar.RecurrenceRule.End to remedy this.

Detailed design

public extension Calendar.RecurrenceRule.End {
    /// At most many times the event may occur
    /// This value is set when the struct was initialized with `.afterOccurrences()`
    @available(FoundationPreview 6.0.2, *)
    public var count: Int? { get }

    /// The latest date when the event may occur
    /// This value is set when the struct was initialized with `.afterDate()`
    @available(FoundationPreview 6.0.2, *)
    public var date: Date? { get }
}

See GitHub PR here: https://github.com/apple/swift-foundation/pull/889

3 Likes

+1 makes complete sense. My only quibble would be that var count should probably be var occurrences, to match the afterOccurrences naming of the static constructor.

3 Likes

Should there also be a property to check for the never case?

extension Calendar.RecurrenceRule.End {
    /// Returns `true` if the event repeats indefinitely.
    public var isNever: Bool { get }
}
2 Likes

Both count and occurrences make sense to me equally. I'm slightly in favour of count as it's more concise, but could be persuaded otherwise.

I think we don't need this as one can simply check for equality with .never.

1 Like

My gut feeling is that the static afterFoo(...) methods should imply a var foo: Type property for naming consistency.

So afterDate(...) causes a var date: Date, and afterOccurrences(...) would imply a var occurrences.

4 Likes

Most of the public APIs in RecurrenceRule.swift have always had comments, but they're missing from the generated documentation.


Should there be a Custom(Debug)StringConvertible conformance, to hide the private enum?

print(Calendar.RecurrenceRule.End.never)
// prints "End(_guts: Foundation.Calendar.RecurrenceRule.End.(unknown context at $1a0a00afc)._End.never)"

I agree, CustomStringConvertible would be great. Adding this to the proposal:

@available(FoundationPreview 6.0.2, *)
public extension Calendar.RecurrenceRule.End: CustomStringConvertible {
    public var description: String {
        switch self._guts {
            case .never: "Never"
            case .afterDate(let date): "After \(date)"
            case .afterOccurrences(let n): "After \(n) occurrences"
        }
    }
}
1 Like

Would it make sense to localize that description somehow?

This is only used when printing, a localized description could fit in localizedDescription. In the context of RecurrenceRule, we would eventually want some sort of formatter to describe what the recurrence is. That is out of scope for this proposal.

1 Like

The review period has ended.

There is one outstanding feedback, but I don't believe that is blocking, so I'll defer to @hsxc for his final decision. Meanwhile I'm going to conclude this review with accepted.

Thank you all.

My bad, I forgot to update the discussion here. I agree with Dave on the naming, and renamed count to occurrences in the proposal: [Proposal] SF-NNNN Extending Calendar.RecurrenceRule.End by hristost · Pull Request #893 · apple/swift-foundation · GitHub

Since there have been no objections, I'll go ahead with merging the proposal and opening the implementation for review.

3 Likes