From 575387c6e16537d2bde9761f150a06e94489def0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Mon, 12 Oct 2026 11:49:42 +0200 Subject: [PATCH] Bring back the Duration helpers as disfavored overloads 1.2.1 shipped Duration.minutes(_:), .hours(_:) and .timeInterval as public API, and the README's log examples use .minutes(30). They were removed on main because HandySwift defines the same three helpers, which made '.minutes(30)' ambiguous in any file importing both modules. Removing them would break every ErrorKit-only user in the next release. Marking them @_disfavoredOverload keeps both cases compiling: alone, ErrorKit's helpers resolve; next to HandySwift, the compiler prefers HandySwift's without an ambiguity error. --- Sources/ErrorKit/Logging/ErrorKit+OSLog.swift | 33 ++++++++++++++++++- Tests/ErrorKitTests/DurationHelperTests.swift | 19 +++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Tests/ErrorKitTests/DurationHelperTests.swift diff --git a/Sources/ErrorKit/Logging/ErrorKit+OSLog.swift b/Sources/ErrorKit/Logging/ErrorKit+OSLog.swift index bc03aa7..f5e129c 100644 --- a/Sources/ErrorKit/Logging/ErrorKit+OSLog.swift +++ b/Sources/ErrorKit/Logging/ErrorKit+OSLog.swift @@ -157,6 +157,8 @@ } } + // HandySwift defines the same three helpers. Disfavoring these lets a file that imports both modules (as FlineDevKit + // does) pick HandySwift's without an ambiguity error, while ErrorKit alone still offers `.minutes(30)` for its log APIs. extension Duration { /// Returns the duration as a `TimeInterval`. /// @@ -169,8 +171,37 @@ /// ``` /// /// - Returns: The duration as a `TimeInterval`, which represents the duration in seconds. - var timeInterval: TimeInterval { + @_disfavoredOverload + public var timeInterval: TimeInterval { TimeInterval(self.components.seconds) + (TimeInterval(self.components.attoseconds) / 1_000_000_000_000_000_000) } + + /// Constructs a `Duration` given a number of minutes represented as a `BinaryInteger`. + /// + /// Example: + /// ```swift + /// try ErrorKit.logAttachment(ofLast: .minutes(30)) + /// ``` + /// + /// - Parameter minutes: The number of minutes. + /// - Returns: A `Duration` representing the given number of minutes. + @_disfavoredOverload + public static func minutes(_ minutes: T) -> Duration { + self.seconds(minutes * 60) + } + + /// Constructs a `Duration` given a number of hours represented as a `BinaryInteger`. + /// + /// Example: + /// ```swift + /// try ErrorKit.logAttachment(ofLast: .hours(1), minLevel: .error) + /// ``` + /// + /// - Parameter hours: The number of hours. + /// - Returns: A `Duration` representing the given number of hours. + @_disfavoredOverload + public static func hours(_ hours: T) -> Duration { + self.seconds(hours * 3600) + } } #endif diff --git a/Tests/ErrorKitTests/DurationHelperTests.swift b/Tests/ErrorKitTests/DurationHelperTests.swift new file mode 100644 index 0000000..cdfa93d --- /dev/null +++ b/Tests/ErrorKitTests/DurationHelperTests.swift @@ -0,0 +1,19 @@ +#if canImport(OSLog) + import Foundation + import Testing + + import ErrorKit + + @Suite("Duration helpers") + struct DurationHelperTests { + @Test func minutesAndHoursBuildTheirDuration() { + #expect(Duration.minutes(30) == .seconds(1800)) + #expect(Duration.hours(2) == .seconds(7200)) + } + + @Test func timeIntervalKeepsFractionalSeconds() { + #expect(Duration.milliseconds(1500).timeInterval == 1.5) + #expect(Duration.hours(1).timeInterval == 3600) + } + } +#endif