From ae46dfc0541f07bf6803efab1237b9410c3aae9e Mon Sep 17 00:00:00 2001 From: Honza Dvorsky Date: Tue, 11 Nov 2025 16:20:24 +0100 Subject: [PATCH] Remove custom key decoders --- Package.swift | 6 +- Sources/Configuration/ConfigKey.swift | 43 + .../Configuration/ConfigReader+methods.swift | 5830 ++--------------- .../ConfigReader+methods.swift.gyb | 1042 +-- Sources/Configuration/ConfigReader.swift | 88 +- .../ConfigSnapshotReader+methods.swift | 1466 +---- .../ConfigSnapshotReader+methods.swift.gyb | 312 - .../Configuration/ConfigSnapshotReader.swift | 85 +- .../Documentation.docc/Documentation.md | 22 +- .../Guides/Troubleshooting.md | 8 +- .../Documentation.docc/Reference/ConfigKey.md | 3 +- .../Reference/ConfigKeyDecoder.md | 12 - .../Reference/ConfigProvider.md | 1 - .../Reference/ConfigReader-Fetch.md | 42 - .../Reference/ConfigReader-Get.md | 42 - .../Reference/ConfigReader-Watch.md | 42 - .../Reference/ConfigReader.md | 7 +- .../Reference/ConfigSnapshotReader.md | 45 +- .../Reference/InMemoryProvider.md | 1 - .../Reference/MutableMemoryProvider.md | 2 - .../Reference/SeparatorKeyDecoder.md | 3 - .../KeyCoders/CLIKeyEncoder.swift | 2 + .../KeyCoders/ConfigKeyDecoder.swift | 63 - .../KeyCoders/ConfigKeyEncoder.swift | 2 +- .../KeyCoders/DotSeparatorKeyDecoder.swift | 30 + .../KeyCoders/SeparatorKeyDecoder.swift | 97 - .../KeyCoders/SeparatorKeyEncoder.swift | 3 + Sources/Configuration/MultiProvider.swift | 6 +- .../EnvironmentKeyEncoder.swift | 6 +- .../Providers/InMemory/InMemoryProvider.swift | 45 - .../InMemory/MutableInMemoryProvider.swift | 77 - .../Wrappers/ConfigProvider+Operators.swift | 18 - .../ProviderCompatTest.swift | 2 +- .../TestProvider.swift | 28 - .../AbsoluteConfigKeyTests.swift | 11 + .../ConfigReaderMethodTestsFetch1.swift | 282 +- .../ConfigReaderMethodTestsFetch1.swift.gyb | 12 +- .../ConfigReaderMethodTestsFetch2.swift | 94 +- .../ConfigReaderMethodTestsFetch2.swift.gyb | 12 +- .../ConfigReaderMethodTestsFetch3.swift | 105 +- .../ConfigReaderMethodTestsFetch3.swift.gyb | 12 +- .../ConfigReaderMethodTestsGet1.swift | 204 +- .../ConfigReaderMethodTestsGet1.swift.gyb | 12 +- .../ConfigReaderMethodTestsGet2.swift | 75 +- .../ConfigReaderMethodTestsGet2.swift.gyb | 12 +- .../ConfigReaderMethodTestsGet3.swift | 88 +- .../ConfigReaderMethodTestsGet3.swift.gyb | 12 +- .../ConfigReaderMethodTestsWatch1.swift | 468 +- .../ConfigReaderMethodTestsWatch1.swift.gyb | 12 +- .../ConfigReaderMethodTestsWatch2.swift | 138 +- .../ConfigReaderMethodTestsWatch2.swift.gyb | 12 +- .../ConfigReaderMethodTestsWatch3.swift | 138 +- .../ConfigReaderMethodTestsWatch3.swift.gyb | 12 +- .../ConfigReaderTests/ConfigReaderTests.swift | 17 +- .../ConfigSnapshotReaderMethodTestsGet1.swift | 210 +- ...figSnapshotReaderMethodTestsGet1.swift.gyb | 12 +- .../ConfigSnapshotReaderMethodTestsGet2.swift | 75 +- ...figSnapshotReaderMethodTestsGet2.swift.gyb | 12 +- .../ConfigSnapshotReaderMethodTestsGet3.swift | 90 +- ...figSnapshotReaderMethodTestsGet3.swift.gyb | 12 +- .../ConfigSnapshotReaderTests.swift | 15 - 61 files changed, 795 insertions(+), 10840 deletions(-) delete mode 100644 Sources/Configuration/Documentation.docc/Reference/ConfigKeyDecoder.md delete mode 100644 Sources/Configuration/Documentation.docc/Reference/SeparatorKeyDecoder.md delete mode 100644 Sources/Configuration/KeyCoders/ConfigKeyDecoder.swift create mode 100644 Sources/Configuration/KeyCoders/DotSeparatorKeyDecoder.swift delete mode 100644 Sources/Configuration/KeyCoders/SeparatorKeyDecoder.swift diff --git a/Package.swift b/Package.swift index f22459b..3216b5c 100644 --- a/Package.swift +++ b/Package.swift @@ -188,7 +188,11 @@ for target in package.targets { // https://docs.swift.org/compiler/documentation/diagnostics/nonisolated-nonsending-by-default/ settings.append(.enableUpcomingFeature("NonisolatedNonsendingByDefault")) - settings.append(.enableExperimentalFeature("AvailabilityMacro=Configuration 1.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0")) + settings.append( + .enableExperimentalFeature( + "AvailabilityMacro=Configuration 1.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0" + ) + ) if enableAllCIFlags { // Ensure all public types are explicitly annotated as Sendable or not Sendable. diff --git a/Sources/Configuration/ConfigKey.swift b/Sources/Configuration/ConfigKey.swift index a120410..dc5af21 100644 --- a/Sources/Configuration/ConfigKey.swift +++ b/Sources/Configuration/ConfigKey.swift @@ -20,6 +20,7 @@ /// /// Keys can include additional context information that some providers use to /// refine value lookups or provide more specific results. +@available(Configuration 1.0, *) public struct ConfigKey: Sendable { /// The hierarchical components that make up this configuration key. @@ -42,10 +43,23 @@ public struct ConfigKey: Sendable { self.components = components self.context = context } + + /// Creates a new configuration key. + /// - Parameters: + /// - string: The string represenation of the key path, for example `"http.timeout"`. + /// - context: Additional context information for the key. + public init(_ string: String, context: [String: ConfigContextValue] = [:]) { + self = DotSeparatorKeyDecoder.decode(string, context: context) + } } +@available(Configuration 1.0, *) extension ConfigKey: Equatable {} + +@available(Configuration 1.0, *) extension ConfigKey: Hashable {} + +@available(Configuration 1.0, *) extension ConfigKey: Comparable { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public static func < (lhs: ConfigKey, rhs: ConfigKey) -> Bool { @@ -67,6 +81,7 @@ extension ConfigKey: Comparable { } } +@available(Configuration 1.0, *) extension ConfigKey: CustomStringConvertible { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public var description: String { @@ -79,6 +94,15 @@ extension ConfigKey: CustomStringConvertible { } } +@available(Configuration 1.0, *) +extension ConfigKey: ExpressibleByStringLiteral { + // swift-format-ignore: AllPublicDeclarationsHaveDocumentation + public init(stringLiteral value: String) { + self = DotSeparatorKeyDecoder.decode(value, context: [:]) + } +} + +@available(Configuration 1.0, *) extension ConfigKey: ExpressibleByArrayLiteral { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public init(arrayLiteral elements: String...) { @@ -94,6 +118,7 @@ extension ConfigKey: ExpressibleByArrayLiteral { /// /// Like relative keys, absolute keys consist of hierarchical components and /// optional context information. +@available(Configuration 1.0, *) public struct AbsoluteConfigKey: Sendable { /// The hierarchical components that make up this absolute configuration key. @@ -118,8 +143,13 @@ public struct AbsoluteConfigKey: Sendable { } } +@available(Configuration 1.0, *) extension AbsoluteConfigKey: Equatable {} + +@available(Configuration 1.0, *) extension AbsoluteConfigKey: Hashable {} + +@available(Configuration 1.0, *) extension AbsoluteConfigKey: Comparable { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public static func < (lhs: AbsoluteConfigKey, rhs: AbsoluteConfigKey) -> Bool { @@ -141,6 +171,7 @@ extension AbsoluteConfigKey: Comparable { } } +@available(Configuration 1.0, *) extension AbsoluteConfigKey: CustomStringConvertible { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public var description: String { @@ -153,6 +184,7 @@ extension AbsoluteConfigKey: CustomStringConvertible { } } +@available(Configuration 1.0, *) extension AbsoluteConfigKey { /// Creates a new absolute configuration key from a relative key. @@ -162,6 +194,7 @@ extension AbsoluteConfigKey { } } +@available(Configuration 1.0, *) extension AbsoluteConfigKey? { /// Returns a new absolute configuration key by appending the given relative key. /// - Parameter relative: The relative configuration key to append to this key. @@ -178,6 +211,7 @@ extension AbsoluteConfigKey? { } } +@available(Configuration 1.0, *) extension AbsoluteConfigKey { /// Returns a new absolute configuration key by prepending the given relative key. /// - Parameter prefix: The relative configuration key to prepend to this key. @@ -201,6 +235,15 @@ extension AbsoluteConfigKey { } } +@available(Configuration 1.0, *) +extension AbsoluteConfigKey: ExpressibleByStringLiteral { + // swift-format-ignore: AllPublicDeclarationsHaveDocumentation + public init(stringLiteral value: String) { + self = .init(DotSeparatorKeyDecoder.decode(value, context: [:])) + } +} + +@available(Configuration 1.0, *) extension AbsoluteConfigKey: ExpressibleByArrayLiteral { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public init(arrayLiteral elements: String...) { diff --git a/Sources/Configuration/ConfigReader+methods.swift b/Sources/Configuration/ConfigReader+methods.swift index d63d762..86bed2e 100644 --- a/Sources/Configuration/ConfigReader+methods.swift +++ b/Sources/Configuration/ConfigReader+methods.swift @@ -55,37 +55,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> String? { - string( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -122,41 +91,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: String, - fileID: String = #fileID, - line: UInt = #line - ) -> String { - string( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -190,38 +124,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> String { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -254,37 +156,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func int( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Int? { - int( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -321,41 +192,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func int( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Int, - fileID: String = #fileID, - line: UInt = #line - ) -> Int { - int( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -389,38 +225,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Int { - try requiredInt( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -453,37 +257,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func double( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Double? { - double( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -520,41 +293,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func double( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Double, - fileID: String = #fileID, - line: UInt = #line - ) -> Double { - double( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -588,38 +326,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Double { - try requiredDouble( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -652,37 +358,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func bool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Bool? { - bool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -719,59 +394,24 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. + /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. + /// Use this method when a configuration value is mandatory for your application to function. + /// The method throws an error if the value is missing or can't be converted to the expected type. /// /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) + /// let apiKey = try config.requiredString(forKey: ["api", "key"], isSecret: true) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func bool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Bool, - fileID: String = #fileID, - line: UInt = #line - ) -> Bool { - bool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let apiKey = try config.requiredString(forKey: ["api", "key"], isSecret: true) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBool( - forKey key: ConfigKey, + /// - Returns: The config value converted to the expected type. + /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. + public func requiredBool( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line @@ -787,38 +427,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Bool { - try requiredBool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -851,37 +459,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func bytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [UInt8]? { - bytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -918,41 +495,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func bytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [UInt8], - fileID: String = #fileID, - line: UInt = #line - ) -> [UInt8] { - bytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -986,38 +528,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [UInt8] { - try requiredBytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -1050,37 +560,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [String]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1117,41 +596,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [String], - fileID: String = #fileID, - line: UInt = #line - ) -> [String] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1185,38 +629,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [String] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -1249,37 +661,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func intArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Int]? { - intArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1316,41 +697,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func intArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Int], - fileID: String = #fileID, - line: UInt = #line - ) -> [Int] { - intArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1384,49 +730,17 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. + /// Synchronously gets a config value for the given config key. /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. + /// Use this method to retrieve optional configuration values. + /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. /// /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") + /// let port = config.int(forKey: ["server", "port"]) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Int] { - try requiredIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a config value for the given config key. - /// - /// Use this method to retrieve optional configuration values. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let port = config.int(forKey: ["server", "port"]) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -1448,37 +762,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func doubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Double]? { - doubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1515,41 +798,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func doubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Double], - fileID: String = #fileID, - line: UInt = #line - ) -> [Double] { - doubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1583,38 +831,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Double] { - try requiredDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -1647,37 +863,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func boolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Bool]? { - boolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1714,41 +899,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func boolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line - ) -> [Bool] { - boolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1782,38 +932,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Bool] { - try requiredBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values. @@ -1846,37 +964,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func byteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [[UInt8]]? { - byteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1913,41 +1000,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func byteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [[UInt8]], - fileID: String = #fileID, - line: UInt = #line - ) -> [[UInt8]] { - byteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1981,38 +1033,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [[UInt8]] { - try requiredByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, converting from string. /// /// Use this method to retrieve configuration values that can be converted from strings, @@ -2048,58 +1068,24 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. + /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result for string-convertible types. + /// If the configuration value is missing or can't be converted to the expected type, + /// the default value is returned instead. /// /// ```swift - /// let serverMode = config.string(forKey: "server.mode", as: ServerMode.self) + /// let serverMode = config.string(forKey: ["server", "mode"], as: ServerMode.self, default: .production) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - type: The type to convert the string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a config value for the given config key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let serverMode = config.string(forKey: ["server", "mode"], as: ServerMode.self, default: .production) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. + /// - Returns: The config value if found and convertible, otherwise the default value. public func string( forKey key: ConfigKey, as type: Value.Type = Value.self, @@ -2120,44 +1106,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = config.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. @@ -2193,41 +1141,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try config.requiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings. @@ -2262,40 +1175,6 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverModes = config.stringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types. @@ -2334,44 +1213,6 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = config.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -2407,41 +1248,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try config.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, converting from string. /// /// Use this method to retrieve configuration values that can be converted from strings, @@ -2477,40 +1283,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. - /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverMode = config.string(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result for string-convertible types. @@ -2549,44 +1321,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = config.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. @@ -2622,41 +1356,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try config.requiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings. @@ -2691,60 +1390,26 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. + /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result for string-convertible array types. + /// If the configuration value is missing or can't be converted to the expected type, + /// the default value is returned instead. /// /// ```swift - /// let serverModes = config.stringArray(forKey: "server.allowedModes", as: ServerMode.self) + /// let serverModes = config.stringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - type: The element type to convert each string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback array returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. + /// - Returns: The config array if found and convertible, otherwise the default array. public func stringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let serverModes = config.stringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray>( - forKey key: ConfigKey, + forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, default defaultValue: [Value], @@ -2763,44 +1428,6 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = config.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -2836,41 +1463,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try config.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - // MARK: - Fetch /// Asynchronously fetches a config value for the given config key. @@ -2908,38 +1500,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> String? { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -2976,41 +1536,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: String, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> String { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -3045,39 +1570,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> String { - try await fetchRequiredString( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -3113,38 +1605,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Int? { - try await fetchInt( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -3181,41 +1641,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Int, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Int { - try await fetchInt( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -3250,39 +1675,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Int { - try await fetchRequiredInt( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -3318,65 +1710,33 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. + /// Asynchronously fetches a config value for the given config key, with a default fallback. /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result from an async provider. + /// If the configuration value is missing, the default value is returned instead. /// /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") + /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. + /// - Returns: The config value if found and convertible, otherwise the default value. /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. public func fetchDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: Double, fileID: String = #fileID, line: UInt = #line - ) async throws -> Double? { - try await fetchDouble( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchDouble( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: Double, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Double { - try await fetchValue( - forKey: key, - type: .double, + ) async throws -> Double { + try await fetchValue( + forKey: key, + type: .double, isSecret: isSecret, default: defaultValue, unwrap: { try $0.asDouble }, @@ -3386,41 +1746,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Double, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Double { - try await fetchDouble( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -3455,39 +1780,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Double { - try await fetchRequiredDouble( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -3523,38 +1815,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Bool? { - try await fetchBool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -3591,41 +1851,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Bool, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Bool { - try await fetchBool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -3660,39 +1885,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Bool { - try await fetchRequiredBool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -3728,38 +1920,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [UInt8]? { - try await fetchBytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -3796,41 +1956,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [UInt8], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [UInt8] { - try await fetchBytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -3865,39 +1990,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [UInt8] { - try await fetchRequiredBytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -3933,104 +2025,37 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. + /// Asynchronously fetches a config value for the given config key, with a default fallback. /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result from an async provider. + /// If the configuration value is missing, the default value is returned instead. /// /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") + /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. + /// - Returns: The config value if found and convertible, otherwise the default value. /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [String], fileID: String = #fileID, line: UInt = #line - ) async throws -> [String]? { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), + ) async throws -> [String] { + try await fetchValue( + forKey: key, + type: .stringArray, isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [String], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [String] { - try await fetchValue( - forKey: key, - type: .stringArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asStringArray }, - wrap: ConfigContent.stringArray, - fileID: fileID, - line: line - ) - } - - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [String], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [String] { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, + default: defaultValue, + unwrap: { try $0.asStringArray }, + wrap: ConfigContent.stringArray, fileID: fileID, line: line ) @@ -4070,39 +2095,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [String] { - try await fetchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -4138,38 +2130,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Int]? { - try await fetchIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -4206,41 +2166,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Int], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Int] { - try await fetchIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -4275,39 +2200,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Int] { - try await fetchRequiredIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -4343,38 +2235,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Double]? { - try await fetchDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -4411,41 +2271,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Double], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Double] { - try await fetchDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -4480,39 +2305,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Double] { - try await fetchRequiredDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -4548,65 +2340,33 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. + /// Asynchronously fetches a config value for the given config key, with a default fallback. /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result from an async provider. + /// If the configuration value is missing, the default value is returned instead. /// /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") + /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. + /// - Returns: The config value if found and convertible, otherwise the default value. /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. public func fetchBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [Bool], fileID: String = #fileID, line: UInt = #line - ) async throws -> [Bool]? { - try await fetchBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: ["network", "maxRetries"], default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBoolArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Bool] { - try await fetchValue( - forKey: key, - type: .boolArray, + ) async throws -> [Bool] { + try await fetchValue( + forKey: key, + type: .boolArray, isSecret: isSecret, default: defaultValue, unwrap: { try $0.asBoolArray }, @@ -4616,41 +2376,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Bool] { - try await fetchBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -4685,39 +2410,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Bool] { - try await fetchRequiredBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key. /// /// Use this method when you need to retrieve configuration values from providers @@ -4753,38 +2445,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [[UInt8]]? { - try await fetchByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -4821,41 +2481,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [[UInt8]], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [[UInt8]] { - try await fetchByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -4890,39 +2515,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [[UInt8]] { - try await fetchRequiredByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, converting from string. /// /// Use this method to retrieve string-convertible configuration values from async providers. @@ -4958,41 +2550,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key, converting from string. - /// - /// Use this method to retrieve string-convertible configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let serverMode = try await config.fetchString(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value? { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. @@ -5031,44 +2588,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevel = try await config.fetchString(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function @@ -5104,41 +2623,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try await config.fetchRequiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings @@ -5174,64 +2658,29 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key, converting from strings. + /// Asynchronously fetches an array of config values for the given config key with default fallback, converting from strings. /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings - /// using async providers. If the value doesn't exist, the method returns `nil`. + /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. + /// If the configuration value is missing, the default value is returned instead. /// /// ```swift - /// let serverModes = try await config.fetchStringArray(forKey: "server.allowedModes", as: ServerMode.self) + /// let serverModes = try await config.fetchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - type: The element type to convert each string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback array returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. + /// - Returns: The config array if found and convertible, otherwise the default array. /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value]? { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Asynchronously fetches an array of config values for the given config key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let serverModes = try await config.fetchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], + default defaultValue: [Value], fileID: String = #fileID, line: UInt = #line ) async throws -> [Value] { @@ -5247,44 +2696,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevels = try await config.fetchStringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function @@ -5320,41 +2731,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try await config.fetchRequiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, converting from string. /// /// Use this method to retrieve string-convertible configuration values from async providers. @@ -5390,41 +2766,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key, converting from string. - /// - /// Use this method to retrieve string-convertible configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let serverMode = try await config.fetchString(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value? { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. @@ -5463,44 +2804,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevel = try await config.fetchString(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function @@ -5536,41 +2839,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try await config.fetchRequiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredString>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings @@ -5606,41 +2874,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings - /// using async providers. If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let serverModes = try await config.fetchStringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value]? { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. @@ -5679,44 +2912,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevels = try await config.fetchStringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function @@ -5752,41 +2947,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try await config.fetchRequiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredStringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - // MARK: - Watch /// Watches for updates to a config value for the given config key. @@ -5835,60 +2995,60 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// print("Server port is: \(port)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: String, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .string, isSecret: isSecret, + default: defaultValue, + unwrap: { try $0.asString }, + wrap: ConfigContent.string, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in + /// for try await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -5897,26 +3057,23 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( + public func watchRequiredString( forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: String, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, type: .string, isSecret: isSecret, - default: defaultValue, unwrap: { try $0.asString }, wrap: ConfigContent.string, fileID: fileID, @@ -5925,59 +3082,61 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to optional configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in + /// try await config.watchInt(forKey: ["server", "port"]) { updates in /// for await port in updates { - /// print("Server port is: \(port)") + /// if let port = port { + /// print("Server port is: \(port)") + /// } else { + /// print("No server port configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchInt( + forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: String, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .int, isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asInt }, + wrap: ConfigContent.int, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given config key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to configuration values that must be present. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in + /// for await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -5986,39 +3145,42 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString( + public func watchInt( forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: Int, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, - type: .string, + type: .int, isSecret: isSecret, - unwrap: { try $0.asString }, - wrap: ConfigContent.string, + default: defaultValue, + unwrap: { try $0.asInt }, + wrap: ConfigContent.int, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given string key. + /// Watches for updates to a required config value for the given config key. /// /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in /// for try await port in updates { /// print("Server port is: \(port)") /// } @@ -6026,8 +3188,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -6035,17 +3196,19 @@ extension ConfigReader { /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchRequiredInt( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchRequiredString( - forKey: keyDecoder.decode(key, context: context), + try await watchRequiredValue( + forKey: key, + type: .int, isSecret: isSecret, + unwrap: { try $0.asInt }, + wrap: ConfigContent.int, fileID: fileID, line: line, updatesHandler: updatesHandler @@ -6079,79 +3242,79 @@ extension ConfigReader { /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchInt( + public func watchDouble( forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { try await watchValue( forKey: key, - type: .int, + type: .double, isSecret: isSecret, - unwrap: { try $0.asInt }, - wrap: ConfigContent.int, + unwrap: { try $0.asDouble }, + wrap: ConfigContent.double, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// print("Server port is: \(port)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchDouble( + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: Double, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchInt( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .double, isSecret: isSecret, + default: defaultValue, + unwrap: { try $0.asDouble }, + wrap: ConfigContent.double, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in + /// for try await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6160,87 +3323,86 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchInt( + public func watchRequiredDouble( forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Int, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, - type: .int, + type: .double, isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asInt }, - wrap: ConfigContent.int, + unwrap: { try $0.asDouble }, + wrap: ConfigContent.double, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to optional configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in + /// try await config.watchInt(forKey: ["server", "port"]) { updates in /// for await port in updates { - /// print("Server port is: \(port)") + /// if let port = port { + /// print("Server port is: \(port)") + /// } else { + /// print("No server port configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchBool( + forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Int, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchInt( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .bool, isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asBool }, + wrap: ConfigContent.bool, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given config key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to configuration values that must be present. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in + /// for await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6249,39 +3411,42 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredInt( + public func watchBool( forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: Bool, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, - type: .int, + type: .bool, isSecret: isSecret, - unwrap: { try $0.asInt }, - wrap: ConfigContent.int, + default: defaultValue, + unwrap: { try $0.asBool }, + wrap: ConfigContent.bool, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given string key. + /// Watches for updates to a required config value for the given config key. /// /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in /// for try await port in updates { /// print("Server port is: \(port)") /// } @@ -6289,8 +3454,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -6298,17 +3462,19 @@ extension ConfigReader { /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchRequiredBool( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchRequiredInt( - forKey: keyDecoder.decode(key, context: context), + try await watchRequiredValue( + forKey: key, + type: .bool, isSecret: isSecret, + unwrap: { try $0.asBool }, + wrap: ConfigContent.bool, fileID: fileID, line: line, updatesHandler: updatesHandler @@ -6342,79 +3508,79 @@ extension ConfigReader { /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDouble( + public func watchBytes( forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8]?, Never>) async throws -> Return ) async throws -> Return { try await watchValue( forKey: key, - type: .double, + type: .bytes, isSecret: isSecret, - unwrap: { try $0.asDouble }, - wrap: ConfigContent.double, + unwrap: { try $0.asBytes }, + wrap: ConfigContent.bytes, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// print("Server port is: \(port)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchBytes( + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [UInt8], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], Never>) async throws -> Return ) async throws -> Return { - try await watchDouble( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .bytes, isSecret: isSecret, + default: defaultValue, + unwrap: { try $0.asBytes }, + wrap: ConfigContent.bytes, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in + /// for try await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6423,87 +3589,86 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDouble( + public func watchRequiredBytes( forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Double, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], any Error>) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, - type: .double, + type: .bytes, isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asDouble }, - wrap: ConfigContent.double, + unwrap: { try $0.asBytes }, + wrap: ConfigContent.bytes, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to optional configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in + /// try await config.watchInt(forKey: ["server", "port"]) { updates in /// for await port in updates { - /// print("Server port is: \(port)") + /// if let port = port { + /// print("Server port is: \(port)") + /// } else { + /// print("No server port configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchStringArray( + forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Double, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[String]?, Never>) async throws -> Return ) async throws -> Return { - try await watchDouble( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .stringArray, isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asStringArray }, + wrap: ConfigContent.stringArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given config key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to configuration values that must be present. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in + /// for await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6512,39 +3677,42 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredDouble( + public func watchStringArray( forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [String], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[String], Never>) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, - type: .double, + type: .stringArray, isSecret: isSecret, - unwrap: { try $0.asDouble }, - wrap: ConfigContent.double, + default: defaultValue, + unwrap: { try $0.asStringArray }, + wrap: ConfigContent.stringArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given string key. + /// Watches for updates to a required config value for the given config key. /// /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in /// for try await port in updates { /// print("Server port is: \(port)") /// } @@ -6552,8 +3720,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -6561,17 +3728,19 @@ extension ConfigReader { /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchRequiredStringArray( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[String], any Error>) async throws -> Return ) async throws -> Return { - try await watchRequiredDouble( - forKey: keyDecoder.decode(key, context: context), + try await watchRequiredValue( + forKey: key, + type: .stringArray, isSecret: isSecret, + unwrap: { try $0.asStringArray }, + wrap: ConfigContent.stringArray, fileID: fileID, line: line, updatesHandler: updatesHandler @@ -6605,79 +3774,79 @@ extension ConfigReader { /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBool( + public func watchIntArray( forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Int]?, Never>) async throws -> Return ) async throws -> Return { try await watchValue( forKey: key, - type: .bool, + type: .intArray, isSecret: isSecret, - unwrap: { try $0.asBool }, - wrap: ConfigContent.bool, + unwrap: { try $0.asIntArray }, + wrap: ConfigContent.intArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// print("Server port is: \(port)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchIntArray( + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [Int], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Int], Never>) async throws -> Return ) async throws -> Return { - try await watchBool( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .intArray, isSecret: isSecret, + default: defaultValue, + unwrap: { try $0.asIntArray }, + wrap: ConfigContent.intArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in + /// for try await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6686,87 +3855,86 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBool( + public func watchRequiredIntArray( forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Bool, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Int], any Error>) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, - type: .bool, + type: .intArray, isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asBool }, - wrap: ConfigContent.bool, + unwrap: { try $0.asIntArray }, + wrap: ConfigContent.intArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to optional configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in + /// try await config.watchInt(forKey: ["server", "port"]) { updates in /// for await port in updates { - /// print("Server port is: \(port)") + /// if let port = port { + /// print("Server port is: \(port)") + /// } else { + /// print("No server port configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchDoubleArray( + forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: Bool, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Double]?, Never>) async throws -> Return ) async throws -> Return { - try await watchBool( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .doubleArray, isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asDoubleArray }, + wrap: ConfigContent.doubleArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given config key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to configuration values that must be present. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in + /// for await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6775,39 +3943,42 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBool( + public func watchDoubleArray( forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [Double], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Double], Never>) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, - type: .bool, + type: .doubleArray, isSecret: isSecret, - unwrap: { try $0.asBool }, - wrap: ConfigContent.bool, + default: defaultValue, + unwrap: { try $0.asDoubleArray }, + wrap: ConfigContent.doubleArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given string key. + /// Watches for updates to a required config value for the given config key. /// /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in /// for try await port in updates { /// print("Server port is: \(port)") /// } @@ -6815,8 +3986,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -6824,17 +3994,19 @@ extension ConfigReader { /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchRequiredDoubleArray( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Double], any Error>) async throws -> Return ) async throws -> Return { - try await watchRequiredBool( - forKey: keyDecoder.decode(key, context: context), + try await watchRequiredValue( + forKey: key, + type: .doubleArray, isSecret: isSecret, + unwrap: { try $0.asDoubleArray }, + wrap: ConfigContent.doubleArray, fileID: fileID, line: line, updatesHandler: updatesHandler @@ -6868,79 +4040,79 @@ extension ConfigReader { /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBytes( + public func watchBoolArray( forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8]?, Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Bool]?, Never>) async throws -> Return ) async throws -> Return { try await watchValue( forKey: key, - type: .bytes, + type: .boolArray, isSecret: isSecret, - unwrap: { try $0.asBytes }, - wrap: ConfigContent.bytes, + unwrap: { try $0.asBoolArray }, + wrap: ConfigContent.boolArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// print("Server port is: \(port)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchBoolArray( + forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [Bool], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8]?, Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], Never>) async throws -> Return ) async throws -> Return { - try await watchBytes( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .boolArray, isSecret: isSecret, + default: defaultValue, + unwrap: { try $0.asBoolArray }, + wrap: ConfigContent.boolArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in + /// for try await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -6949,87 +4121,86 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBytes( + public func watchRequiredBoolArray( forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: [UInt8], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], any Error>) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, - type: .bytes, + type: .boolArray, isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asBytes }, - wrap: ConfigContent.bytes, + unwrap: { try $0.asBoolArray }, + wrap: ConfigContent.boolArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to optional configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in + /// try await config.watchInt(forKey: ["server", "port"]) { updates in /// for await port in updates { - /// print("Server port is: \(port)") + /// if let port = port { + /// print("Server port is: \(port)") + /// } else { + /// print("No server port configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchByteChunkArray( + forKey key: ConfigKey, isSecret: Bool = false, - default defaultValue: [UInt8], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]]?, Never>) async throws -> Return ) async throws -> Return { - try await watchBytes( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .byteChunkArray, isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asByteChunkArray }, + wrap: ConfigContent.byteChunkArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given config key. + /// Watches for updates to a config value for the given config key with default fallback. /// - /// Use this method to observe changes to configuration values that must be present. + /// Use this method to observe changes to configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { + /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in + /// for await port in updates { /// print("Server port is: \(port)") /// } /// } @@ -7038,39 +4209,42 @@ extension ConfigReader { /// - Parameters: /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBytes( + public func watchByteChunkArray( forKey key: ConfigKey, isSecret: Bool = false, + default defaultValue: [[UInt8]], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], any Error>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], Never>) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, - type: .bytes, + type: .byteChunkArray, isSecret: isSecret, - unwrap: { try $0.asBytes }, - wrap: ConfigContent.bytes, + default: defaultValue, + unwrap: { try $0.asByteChunkArray }, + wrap: ConfigContent.byteChunkArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required config value for the given string key. + /// Watches for updates to a required config value for the given config key. /// /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, /// or an error if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in + /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in /// for try await port in updates { /// print("Server port is: \(port)") /// } @@ -7078,8 +4252,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -7087,36 +4260,38 @@ extension ConfigReader { /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchRequiredByteChunkArray( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[UInt8], any Error>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], any Error>) async throws -> Return ) async throws -> Return { - try await watchRequiredBytes( - forKey: keyDecoder.decode(key, context: context), + try await watchRequiredValue( + forKey: key, + type: .byteChunkArray, isSecret: isSecret, + unwrap: { try $0.asByteChunkArray }, + wrap: ConfigContent.byteChunkArray, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key. + /// Watches for updates to a config value for the given config key, converting from string. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to optional string-convertible configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"]) { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") + /// try await config.watchString(forKey: ["server", "mode"], as: ServerMode.self) { updates in + /// for await mode in updates { + /// if let mode = mode { + /// print("Server mode is: \(mode.description)") /// } else { - /// print("No server port configured") + /// print("No server mode configured") /// } /// } /// } @@ -7124,6 +4299,7 @@ extension ConfigReader { /// /// - Parameters: /// - key: The config key to watch. + /// - type: The type to convert the string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -7131,1771 +4307,174 @@ extension ConfigReader { /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( + public func watchString( forKey key: ConfigKey, + as type: Value.Type = Value.self, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String]?, Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { try await watchValue( forKey: key, - type: .stringArray, + type: .string, isSecret: isSecret, - unwrap: { try $0.asStringArray }, - wrap: ConfigContent.stringArray, + unwrap: { try cast($0.asString, type: Value.self, key: key) }, + wrap: { uncast($0) }, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key. + /// Watches for updates to a config value for the given config key with default fallback, converting from string. /// - /// Use this method to observe changes to optional configuration values over time. + /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } + /// try await config.watchString(forKey: ["server", "mode"], as: ServerMode.self, default: .production) { updates in + /// for await mode in updates { + /// print("Server mode is: \(mode.description)") /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. + /// - type: The type to convert the string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchString( + forKey key: ConfigKey, + as type: Value.Type = Value.self, isSecret: Bool = false, + default defaultValue: Value, fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String]?, Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .string, isSecret: isSecret, + default: defaultValue, + unwrap: { try cast($0.asString, type: Value.self, key: key) }, + wrap: { uncast($0) }, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given config key with default fallback. + /// Watches for updates to a required config value for the given config key, converting from string. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to mandatory string-convertible configuration values over time. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// or an error if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") + /// try await config.watchRequiredString(forKey: ["server", "mode"], as: ServerMode.self) { updates in + /// for try await mode in updates { + /// print("Server mode is: \(mode.description)") /// } /// } /// ``` /// /// - Parameters: /// - key: The config key to watch. + /// - type: The type to convert the string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( + public func watchRequiredString( forKey key: ConfigKey, + as type: Value.Type = Value.self, isSecret: Bool = false, - default defaultValue: [String], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String], Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return ) async throws -> Return { - try await watchValue( + try await watchRequiredValue( forKey: key, - type: .stringArray, + type: .string, isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asStringArray }, - wrap: ConfigContent.stringArray, + unwrap: { try cast($0.asString, type: Value.self, key: key) }, + wrap: { uncast($0) }, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to an array of config values for the given config key, converting from strings. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. + /// Use this method to observe changes to optional string-convertible array configuration values over time. + /// The handler receives an async sequence that produces the current array whenever it changes, + /// or `nil` if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") + /// try await config.watchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self) { updates in + /// for await modes in updates { + /// if let modes = modes { + /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") + /// } else { + /// print("No server modes configured") + /// } /// } /// } /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. + /// - type: The element type to convert each string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. + /// produces `nil` if the value is missing or can't be converted. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + public func watchStringArray( + forKey key: ConfigKey, + as type: Value.Type = Value.self, isSecret: Bool = false, - default defaultValue: [String], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String], Never>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Value]?, Never>) async throws -> Return ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), + try await watchValue( + forKey: key, + type: .stringArray, isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredStringArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .stringArray, - isSecret: isSecret, - unwrap: { try $0.asStringArray }, - wrap: ConfigContent.stringArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[String], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"]) { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchIntArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .intArray, - isSecret: isSecret, - unwrap: { try $0.asIntArray }, - wrap: ConfigContent.intArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchIntArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [Int], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int], Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .intArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asIntArray }, - wrap: ConfigContent.intArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Int], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int], Never>) async throws -> Return - ) async throws -> Return { - try await watchIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredIntArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .intArray, - isSecret: isSecret, - unwrap: { try $0.asIntArray }, - wrap: ConfigContent.intArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Int], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"]) { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDoubleArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .doubleArray, - isSecret: isSecret, - unwrap: { try $0.asDoubleArray }, - wrap: ConfigContent.doubleArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDoubleArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [Double], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double], Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .doubleArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asDoubleArray }, - wrap: ConfigContent.doubleArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Double], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double], Never>) async throws -> Return - ) async throws -> Return { - try await watchDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredDoubleArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .doubleArray, - isSecret: isSecret, - unwrap: { try $0.asDoubleArray }, - wrap: ConfigContent.doubleArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Double], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"]) { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBoolArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .boolArray, - isSecret: isSecret, - unwrap: { try $0.asBoolArray }, - wrap: ConfigContent.boolArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBoolArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .boolArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asBoolArray }, - wrap: ConfigContent.boolArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], Never>) async throws -> Return - ) async throws -> Return { - try await watchBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBoolArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .boolArray, - isSecret: isSecret, - unwrap: { try $0.asBoolArray }, - wrap: ConfigContent.boolArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Bool], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"]) { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchByteChunkArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .byteChunkArray, - isSecret: isSecret, - unwrap: { try $0.asByteChunkArray }, - wrap: ConfigContent.byteChunkArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: ["server", "port"], default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchByteChunkArray( - forKey key: ConfigKey, - isSecret: Bool = false, - default defaultValue: [[UInt8]], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .byteChunkArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asByteChunkArray }, - wrap: ConfigContent.byteChunkArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key with default fallback. - /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [[UInt8]], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], Never>) async throws -> Return - ) async throws -> Return { - try await watchByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredByteChunkArray( - forKey key: ConfigKey, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .byteChunkArray, - isSecret: isSecret, - unwrap: { try $0.asByteChunkArray }, - wrap: ConfigContent.byteChunkArray, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[[UInt8]], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key, converting from string. - /// - /// Use this method to observe changes to optional string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: ["server", "mode"], as: ServerMode.self) { updates in - /// for await mode in updates { - /// if let mode = mode { - /// print("Server mode is: \(mode.description)") - /// } else { - /// print("No server mode configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .string, - isSecret: isSecret, - unwrap: { try cast($0.asString, type: Value.self, key: key) }, - wrap: { uncast($0) }, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key, converting from string. - /// - /// Use this method to observe changes to optional string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for await mode in updates { - /// if let mode = mode { - /// print("Server mode is: \(mode.description)") - /// } else { - /// print("No server mode configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given config key with default fallback, converting from string. - /// - /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: ["server", "mode"], as: ServerMode.self, default: .production) { updates in - /// for await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .string, - isSecret: isSecret, - default: defaultValue, - unwrap: { try cast($0.asString, type: Value.self, key: key) }, - wrap: { uncast($0) }, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a config value for the given string key with default fallback, converting from string. - /// - /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self, default: .production) { updates in - /// for await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key, converting from string. - /// - /// Use this method to observe changes to mandatory string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredString(forKey: ["server", "mode"], as: ServerMode.self) { updates in - /// for try await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchRequiredValue( - forKey: key, - type: .string, - isSecret: isSecret, - unwrap: { try cast($0.asString, type: Value.self, key: key) }, - wrap: { uncast($0) }, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given string key, converting from string. - /// - /// Use this method to observe changes to mandatory string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for try await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to an array of config values for the given config key, converting from strings. - /// - /// Use this method to observe changes to optional string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self) { updates in - /// for await modes in updates { - /// if let modes = modes { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } else { - /// print("No server modes configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .stringArray, - isSecret: isSecret, - unwrap: { try $0.asStringArray.map { try cast($0, type: Value.self, key: key) } }, - wrap: { uncast($0) }, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to an array of config values for the given string key, converting from strings. - /// - /// Use this method to observe changes to optional string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in - /// for await modes in updates { - /// if let modes = modes { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } else { - /// print("No server modes configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to an array of config values for the given config key with default fallback, converting from strings. - /// - /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) { updates in - /// for await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The config key to watch. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], Never>) async throws -> Return - ) async throws -> Return { - try await watchValue( - forKey: key, - type: .stringArray, - isSecret: isSecret, - default: defaultValue, - unwrap: { try $0.asStringArray.map { try cast($0, type: Value.self, key: key) } }, - wrap: { uncast($0) }, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self, default: [.production]) { updates in - /// for await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, + unwrap: { try $0.asStringArray.map { try cast($0, type: Value.self, key: key) } }, + wrap: { uncast($0) }, fileID: fileID, line: line, updatesHandler: updatesHandler ) } - /// Watches for updates to a required array of config values for the given config key, converting from strings. + /// Watches for updates to an array of config values for the given config key with default fallback, converting from strings. /// - /// Use this method to observe changes to mandatory string-convertible array configuration values over time. + /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. /// The handler receives an async sequence that produces the current array whenever it changes, - /// or throws an error if the value is missing or can't be converted. + /// or the default value if the configuration value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self) { updates in - /// for try await modes in updates { + /// try await config.watchStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self, default: [.production]) { updates in + /// for await modes in updates { /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") /// } /// } @@ -8905,24 +4484,27 @@ extension ConfigReader { /// - key: The config key to watch. /// - type: The element type to convert each string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. + /// - defaultValue: The fallback array used when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. + /// produces the default value if the provider returned a `nil` value or conversion failed. /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredStringArray( + public func watchStringArray( forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, + default defaultValue: [Value], fileID: String = #fileID, line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], any Error>) async throws -> Return + updatesHandler: (ConfigUpdatesAsyncSequence<[Value], Never>) async throws -> Return ) async throws -> Return { - try await watchRequiredValue( + try await watchValue( forKey: key, type: .stringArray, isSecret: isSecret, + default: defaultValue, unwrap: { try $0.asStringArray.map { try cast($0, type: Value.self, key: key) } }, wrap: { uncast($0) }, fileID: fileID, @@ -8931,14 +4513,14 @@ extension ConfigReader { ) } - /// Watches for updates to a required array of config values for the given string key, converting from strings. + /// Watches for updates to a required array of config values for the given config key, converting from strings. /// /// Use this method to observe changes to mandatory string-convertible array configuration values over time. /// The handler receives an async sequence that produces the current array whenever it changes, /// or throws an error if the value is missing or can't be converted. /// /// ```swift - /// try await config.watchRequiredStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in + /// try await config.watchRequiredStringArray(forKey: ["server", "allowedModes"], as: ServerMode.self) { updates in /// for try await modes in updates { /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") /// } @@ -8946,8 +4528,7 @@ extension ConfigReader { /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. + /// - key: The config key to watch. /// - type: The element type to convert each string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. @@ -8957,18 +4538,19 @@ extension ConfigReader { /// - Returns: The result produced by the handler. /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. public func watchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line, updatesHandler: (ConfigUpdatesAsyncSequence<[Value], any Error>) async throws -> Return ) async throws -> Return { - try await watchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, + try await watchRequiredValue( + forKey: key, + type: .stringArray, isSecret: isSecret, + unwrap: { try $0.asStringArray.map { try cast($0, type: Value.self, key: key) } }, + wrap: { uncast($0) }, fileID: fileID, line: line, updatesHandler: updatesHandler @@ -9023,54 +4605,6 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key, converting from string. - /// - /// Use this method to observe changes to optional string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for await mode in updates { - /// if let mode = mode { - /// print("Server mode is: \(mode.description)") - /// } else { - /// print("No server mode configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a config value for the given config key with default fallback, converting from string. /// /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. @@ -9118,53 +4652,6 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key with default fallback, converting from string. - /// - /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self, default: .production) { updates in - /// for await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a required config value for the given config key, converting from string. /// /// Use this method to observe changes to mandatory string-convertible configuration values over time. @@ -9209,50 +4696,6 @@ extension ConfigReader { ) } - /// Watches for updates to a required config value for the given string key, converting from string. - /// - /// Use this method to observe changes to mandatory string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for try await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to an array of config values for the given config key, converting from strings. /// /// Use this method to observe changes to optional string-convertible array configuration values over time. @@ -9301,54 +4744,6 @@ extension ConfigReader { ) } - /// Watches for updates to an array of config values for the given string key, converting from strings. - /// - /// Use this method to observe changes to optional string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in - /// for await modes in updates { - /// if let modes = modes { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } else { - /// print("No server modes configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. @@ -9396,53 +4791,6 @@ extension ConfigReader { ) } - /// Watches for updates to an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self, default: [.production]) { updates in - /// for await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a required array of config values for the given config key, converting from strings. /// /// Use this method to observe changes to mandatory string-convertible array configuration values over time. @@ -9487,48 +4835,4 @@ extension ConfigReader { ) } - /// Watches for updates to a required array of config values for the given string key, converting from strings. - /// - /// Use this method to observe changes to mandatory string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or throws an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in - /// for try await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredStringArray & Sendable, Return>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - } diff --git a/Sources/Configuration/ConfigReader+methods.swift.gyb b/Sources/Configuration/ConfigReader+methods.swift.gyb index 4204569..3793874 100644 --- a/Sources/Configuration/ConfigReader+methods.swift.gyb +++ b/Sources/Configuration/ConfigReader+methods.swift.gyb @@ -54,37 +54,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = config.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func ${primitive_type["lowercase_name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> ${primitive_type["type"]}? { - ${primitive_type["lowercase_name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -121,41 +90,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = config.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func ${primitive_type["lowercase_name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: ${primitive_type["type"]}, - fileID: String = #fileID, - line: UInt = #line - ) -> ${primitive_type["type"]} { - ${primitive_type["lowercase_name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -189,38 +123,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try config.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func required${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> ${primitive_type["type"]} { - try required${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end % for string_convertible_type in string_convertible_types: /// Synchronously gets a config value for the given config key, converting from string. @@ -258,40 +160,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. - /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverMode = config.string(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result for string-convertible types. @@ -330,44 +198,6 @@ extension ConfigReader { ) } - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = config.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. @@ -403,41 +233,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try config.requiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings. @@ -472,40 +267,6 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverModes = config.stringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types. @@ -544,44 +305,6 @@ extension ConfigReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = config.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -617,41 +340,6 @@ extension ConfigReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try config.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end // MARK: - Fetch @@ -691,38 +379,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = try await config.fetchString(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetch${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> ${primitive_type["type"]}? { - try await fetch${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result from an async provider. @@ -759,41 +415,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given config key, with a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let maxRetries = try await config.fetchInt(forKey: "network.maxRetries", default: 3) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetch${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: ${primitive_type["type"]}, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> ${primitive_type["type"]} { - try await fetch${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function @@ -828,39 +449,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is - /// missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try await config.fetchRequiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequired${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> ${primitive_type["type"]} { - try await fetchRequired${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end % for string_convertible_type in string_convertible_types: /// Asynchronously fetches a config value for the given config key, converting from string. @@ -898,41 +486,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key, converting from string. - /// - /// Use this method to retrieve string-convertible configuration values from async providers. - /// If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let serverMode = try await config.fetchString(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value? { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. @@ -971,44 +524,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result from an async provider for string-convertible types. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevel = try await config.fetchString(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function @@ -1044,41 +559,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try await config.fetchRequiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> Value { - try await fetchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings @@ -1114,41 +594,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings - /// using async providers. If the value doesn't exist, the method returns `nil`. - /// - /// ```swift - /// let serverModes = try await config.fetchStringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value]? { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. @@ -1187,44 +632,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types from async providers. - /// If the configuration value is missing, the default value is returned instead. - /// - /// ```swift - /// let logLevels = try await config.fetchStringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - /// - Throws: If the underlying provider throws, or if the value can't be converted to the expected type. - public func fetchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Asynchronously fetches a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function @@ -1260,41 +667,6 @@ extension ConfigReader { ) } - /// Asynchronously fetches a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function - /// and you're working with async providers. The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try await config.fetchRequiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the underlying provider throws, the value is missing, or can't be converted to the expected type. - public func fetchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) async throws -> [Value] { - try await fetchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end // MARK: - Watch @@ -1345,51 +717,6 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key. - /// - /// Use this method to observe changes to optional configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port") { updates in - /// for await port in updates { - /// if let port = port { - /// print("Server port is: \(port)") - /// } else { - /// print("No server port configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watch${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<${primitive_type["type"]}?, Never>) async throws -> Return - ) async throws -> Return { - try await watch${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a config value for the given config key with default fallback. /// /// Use this method to observe changes to configuration values over time with a guaranteed fallback. @@ -1435,55 +762,11 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key with default fallback. + /// Watches for updates to a required config value for the given config key. /// - /// Use this method to observe changes to configuration values over time with a guaranteed fallback. + /// Use this method to observe changes to configuration values that must be present. /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchInt(forKey: "server.port", default: 8080) { updates in - /// for await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watch${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: ${primitive_type["type"]}, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<${primitive_type["type"]}, Never>) async throws -> Return - ) async throws -> Return { - try await watch${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - - /// Watches for updates to a required config value for the given config key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. + /// or an error if the configuration value is missing or can't be converted. /// /// ```swift /// try await config.watchRequiredInt(forKey: ["server", "port"]) { updates in @@ -1521,47 +804,6 @@ extension ConfigReader { ) } - /// Watches for updates to a required config value for the given string key. - /// - /// Use this method to observe changes to configuration values that must be present. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredInt(forKey: "server.port") { updates in - /// for try await port in updates { - /// print("Server port is: \(port)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequired${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<${primitive_type["type"]}, any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequired${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - % end % for string_convertible_type in string_convertible_types: /// Watches for updates to a config value for the given config key, converting from string. @@ -1612,54 +854,6 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key, converting from string. - /// - /// Use this method to observe changes to optional string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for await mode in updates { - /// if let mode = mode { - /// print("Server mode is: \(mode.description)") - /// } else { - /// print("No server mode configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a config value for the given config key with default fallback, converting from string. /// /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. @@ -1707,53 +901,6 @@ extension ConfigReader { ) } - /// Watches for updates to a config value for the given string key with default fallback, converting from string. - /// - /// Use this method to observe changes to string-convertible configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchString(forKey: "server.mode", as: ServerMode.self, default: .production) { updates in - /// for await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a required config value for the given config key, converting from string. /// /// Use this method to observe changes to mandatory string-convertible configuration values over time. @@ -1798,50 +945,6 @@ extension ConfigReader { ) } - /// Watches for updates to a required config value for the given string key, converting from string. - /// - /// Use this method to observe changes to mandatory string-convertible configuration values over time. - /// The handler receives an async sequence that produces the current value whenever it changes, - /// or an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredString(forKey: "server.mode", as: ServerMode.self) { updates in - /// for try await mode in updates { - /// print("Server mode is: \(mode.description)") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence) async throws -> Return - ) async throws -> Return { - try await watchRequiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to an array of config values for the given config key, converting from strings. /// /// Use this method to observe changes to optional string-convertible array configuration values over time. @@ -1890,54 +993,6 @@ extension ConfigReader { ) } - /// Watches for updates to an array of config values for the given string key, converting from strings. - /// - /// Use this method to observe changes to optional string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or `nil` if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in - /// for await modes in updates { - /// if let modes = modes { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } else { - /// print("No server modes configured") - /// } - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces `nil` if the value is missing or can't be converted. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value]?, Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. @@ -1985,53 +1040,6 @@ extension ConfigReader { ) } - /// Watches for updates to an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method to observe changes to string-convertible array configuration values over time with a guaranteed fallback. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or the default value if the configuration value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchStringArray(forKey: "server.allowedModes", as: ServerMode.self, default: [.production]) { updates in - /// for await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array used when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces the default value if the provider returned a `nil` value or conversion failed. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], Never>) async throws -> Return - ) async throws -> Return { - try await watchStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - /// Watches for updates to a required array of config values for the given config key, converting from strings. /// /// Use this method to observe changes to mandatory string-convertible array configuration values over time. @@ -2076,49 +1084,5 @@ extension ConfigReader { ) } - /// Watches for updates to a required array of config values for the given string key, converting from strings. - /// - /// Use this method to observe changes to mandatory string-convertible array configuration values over time. - /// The handler receives an async sequence that produces the current array whenever it changes, - /// or throws an error if the value is missing or can't be converted. - /// - /// ```swift - /// try await config.watchRequiredStringArray(forKey: "server.allowedModes", as: ServerMode.self) { updates in - /// for try await modes in updates { - /// print("Allowed server modes: \(modes.map(\.description).joined(separator: ", "))") - /// } - /// } - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to watch. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - updatesHandler: A closure that handles an async sequence of updates to the value. The sequence - /// produces an error if the provider returned a `nil` value or if the value was of an incorrect type. - /// - Returns: The result produced by the handler. - /// - Throws: Rethrows any error thrown by the handler or the underlying watch operation. - public func watchRequiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line, - updatesHandler: (ConfigUpdatesAsyncSequence<[Value], any Error>) async throws -> Return - ) async throws -> Return { - try await watchRequiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line, - updatesHandler: updatesHandler - ) - } - % end } diff --git a/Sources/Configuration/ConfigReader.swift b/Sources/Configuration/ConfigReader.swift index 9ea01a5..fba2fcd 100644 --- a/Sources/Configuration/ConfigReader.swift +++ b/Sources/Configuration/ConfigReader.swift @@ -92,13 +92,12 @@ import Foundation /// ### Using configuration context /// /// Provide additional context to help providers return more specific values. In the following example -/// with a configuration that includes repeated configurations per "upstream" side, the value returned is +/// with a configuration that includes repeated configurations per "upstream", the value returned is /// potentially constrained to the configuration with the matching context: /// /// ```swift /// let httpTimeout = config.int( -/// forKey: "http.timeout", -/// context: ["upstream": "example.com"], +/// forKey: ConfigKey("http.timeout", context: ["upstream": "example.com"]), /// default: 60 /// ) /// ``` @@ -153,19 +152,6 @@ import Foundation /// ) /// ``` /// -/// ### Customizing key decoding -/// -/// By default, config keys use a dot-separated notation (`http.timeout` becomes `["http", "timeout"]`). -/// The ``ConfigKeyDecoder`` handles this parsing, with ``ConfigReader`` using -/// ``ConfigKeyDecoder/dotSeparated`` by default. -/// -/// To use different key separators, provide a custom decoder: -/// -/// ```swift -/// let config = ConfigReader(keyDecoder: .colonSeparated, provider: provider) -/// let httpTimeout = config.int(forKey: "http:timeout", default: 60) -/// ``` -/// /// ### How providers encode keys /// /// Each ``ConfigProvider`` interprets config keys according to its data source format. @@ -218,8 +204,7 @@ import Foundation /// /// ```swift /// let dbConfig = config.string( -/// forKey: "database.url", -/// context: ["environment": "staging"], +/// forKey: ConfigKey("database.url", context: ["environment": "staging"]), /// default: "localhost:5432" /// ) /// ``` @@ -248,11 +233,6 @@ public struct ConfigReader: Sendable { /// from this one. private final class Storage: Sendable { - /// The decoder that converts string keys into config key arrays. - /// - /// For example, converts the string`foo.bar.baz` into its array representation `["foo", "bar", "baz"]`. - let keyDecoder: any ConfigKeyDecoder - /// The underlying multi provider. let provider: MultiProvider @@ -261,15 +241,12 @@ public struct ConfigReader: Sendable { /// Creates a storage instance. /// - Parameters: - /// - keyDecoder: The decoder for converting string keys to config keys. /// - provider: The multi-provider that manages the provider hierarchy. /// - accessReporter: The reporter for configuration access events. init( - keyDecoder: some ConfigKeyDecoder, provider: MultiProvider, accessReporter: (any AccessReporter)? ) { - self.keyDecoder = keyDecoder self.provider = provider self.accessReporter = accessReporter } @@ -292,11 +269,9 @@ public struct ConfigReader: Sendable { /// Creates a config reader with multiple providers. /// - Parameters: - /// - keyDecoder: The decoder that converts string keys to config keys. /// - providers: The configuration providers, queried in order until a value is found. /// - accessReporter: The reporter for configuration access events. public init( - keyDecoder: some ConfigKeyDecoder = .dotSeparated, providers: [any ConfigProvider], accessReporter: (any AccessReporter)? = nil ) { @@ -317,7 +292,6 @@ public struct ConfigReader: Sendable { self.init( keyPrefix: nil, storage: .init( - keyDecoder: keyDecoder, provider: MultiProvider(providers: providers), accessReporter: reporter ) @@ -330,16 +304,13 @@ extension ConfigReader { /// Creates a config reader with a single provider. /// - Parameters: - /// - keyDecoder: The decoder that converts string keys to config keys. /// - provider: The configuration provider. /// - accessReporter: The reporter for configuration access events. public init( - keyDecoder: some ConfigKeyDecoder = .dotSeparated, provider: some ConfigProvider, accessReporter: (any AccessReporter)? = nil ) { self.init( - keyDecoder: keyDecoder, providers: [provider], accessReporter: accessReporter ) @@ -349,21 +320,10 @@ extension ConfigReader { /// - Parameters: /// - scopedKey: The key components to append to the current key prefix. /// - parent: The parent config reader from which to create the scoped reader. - /// - keyDecoderOverride: An optional key decoder that replaces the parent's decoder. - private init(scopedKey: ConfigKey, parent: ConfigReader, keyDecoderOverride: (any ConfigKeyDecoder)?) { - let storage: Storage - if let keyDecoderOverride { - storage = .init( - keyDecoder: keyDecoderOverride, - provider: parent.storage.provider, - accessReporter: parent.storage.accessReporter - ) - } else { - storage = parent.storage - } + private init(scopedKey: ConfigKey, parent: ConfigReader) { self.init( keyPrefix: parent.keyPrefix.appending(scopedKey), - storage: storage + storage: parent.storage ) } @@ -374,39 +334,12 @@ extension ConfigReader { /// let timeout = httpConfig.int(forKey: "timeout", default: 30) // Reads "http.client.timeout" /// ``` /// - /// - Parameters: - /// - configKey: The key components to append to the current key prefix. - /// - keyDecoderOverride: An optional key decoder that replaces the current decoder. + /// - Parameter configKey: The key components to append to the current key prefix. /// - Returns: A config reader for accessing values within the specified scope. - public func scoped(to configKey: ConfigKey, keyDecoderOverride: (any ConfigKeyDecoder)? = nil) -> ConfigReader { + public func scoped(to configKey: ConfigKey) -> ConfigReader { ConfigReader( scopedKey: configKey, - parent: self, - keyDecoderOverride: keyDecoderOverride - ) - } - - /// Returns a scoped config reader with the specified string key appended to the current prefix. - /// - /// ```swift - /// let dbConfig = config.scoped(to: "database") - /// let host = dbConfig.string(forKey: "host", default: "localhost") // Reads "database.host" - /// ``` - /// - /// - Parameters: - /// - key: The string key to decode and append to the current key prefix. - /// - context: Additional context used when decoding the key. - /// - keyDecoderOverride: An optional key decoder that replaces the current decoder. - /// - Returns: A config reader for accessing values within the specified scope. - public func scoped( - to key: String, - context: [String: ConfigContextValue] = [:], - keyDecoderOverride: (any ConfigKeyDecoder)? = nil - ) -> ConfigReader { - ConfigReader( - scopedKey: (keyDecoderOverride ?? keyDecoder).decode(key, context: context), - parent: self, - keyDecoderOverride: keyDecoderOverride + parent: self ) } } @@ -416,11 +349,6 @@ extension ConfigReader { @available(Configuration 1.0, *) extension ConfigReader { - /// The decoder the library uses to convert string keys into config keys. - var keyDecoder: any ConfigKeyDecoder { - storage.keyDecoder - } - /// The multi-provider that manages the hierarchy of configuration providers. var provider: MultiProvider { storage.provider diff --git a/Sources/Configuration/ConfigSnapshotReader+methods.swift b/Sources/Configuration/ConfigSnapshotReader+methods.swift index f9f1fcf..24c7fb2 100644 --- a/Sources/Configuration/ConfigSnapshotReader+methods.swift +++ b/Sources/Configuration/ConfigSnapshotReader+methods.swift @@ -55,37 +55,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> String? { - string( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -122,41 +91,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: String, - fileID: String = #fileID, - line: UInt = #line - ) -> String { - string( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -190,38 +124,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> String { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -254,37 +156,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func int( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Int? { - int( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -321,41 +192,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func int( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Int, - fileID: String = #fileID, - line: UInt = #line - ) -> Int { - int( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -389,38 +225,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredInt( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Int { - try requiredInt( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -453,37 +257,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func double( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Double? { - double( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -520,41 +293,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func double( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Double, - fileID: String = #fileID, - line: UInt = #line - ) -> Double { - double( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -588,38 +326,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredDouble( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Double { - try requiredDouble( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -652,37 +358,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func bool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Bool? { - bool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -719,59 +394,24 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. + /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. + /// Use this method when a configuration value is mandatory for your application to function. + /// The method throws an error if the value is missing or can't be converted to the expected type. /// /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) + /// let apiKey = try snapshot.requiredString(forKey: ["api", "key"], isSecret: true) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func bool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: Bool, - fileID: String = #fileID, - line: UInt = #line - ) -> Bool { - bool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let apiKey = try snapshot.requiredString(forKey: ["api", "key"], isSecret: true) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBool( - forKey key: ConfigKey, + /// - Returns: The config value converted to the expected type. + /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. + public func requiredBool( + forKey key: ConfigKey, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line @@ -787,38 +427,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBool( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Bool { - try requiredBool( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -851,37 +459,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func bytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [UInt8]? { - bytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -918,41 +495,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func bytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [UInt8], - fileID: String = #fileID, - line: UInt = #line - ) -> [UInt8] { - bytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -986,38 +528,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBytes( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [UInt8] { - try requiredBytes( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -1050,37 +560,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [String]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1117,41 +596,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [String], - fileID: String = #fileID, - line: UInt = #line - ) -> [String] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1185,38 +629,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [String] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -1249,37 +661,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func intArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Int]? { - intArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1316,41 +697,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func intArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Int], - fileID: String = #fileID, - line: UInt = #line - ) -> [Int] { - intArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1384,49 +730,17 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. + /// Synchronously gets a config value for the given config key. /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. + /// Use this method to retrieve optional configuration values from a snapshot. + /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. /// /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") + /// let port = snapshot.int(forKey: ["server", "port"]) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredIntArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Int] { - try requiredIntArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a config value for the given config key. - /// - /// Use this method to retrieve optional configuration values from a snapshot. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let port = snapshot.int(forKey: ["server", "port"]) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. + /// - key: The config key to look up. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. @@ -1448,37 +762,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func doubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Double]? { - doubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1515,41 +798,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func doubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Double], - fileID: String = #fileID, - line: UInt = #line - ) -> [Double] { - doubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1583,38 +831,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredDoubleArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Double] { - try requiredDoubleArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -1647,37 +863,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func boolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Bool]? { - boolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1714,41 +899,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func boolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [Bool], - fileID: String = #fileID, - line: UInt = #line - ) -> [Bool] { - boolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1782,38 +932,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredBoolArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Bool] { - try requiredBoolArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key. /// /// Use this method to retrieve optional configuration values from a snapshot. @@ -1846,37 +964,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func byteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [[UInt8]]? { - byteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -1913,41 +1000,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func byteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: [[UInt8]], - fileID: String = #fileID, - line: UInt = #line - ) -> [[UInt8]] { - byteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -1981,38 +1033,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredByteChunkArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [[UInt8]] { - try requiredByteChunkArray( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, converting from string. /// /// Use this method to retrieve configuration values that can be converted from strings, @@ -2048,40 +1068,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. - /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverMode = snapshot.string(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result for string-convertible types. @@ -2099,93 +1085,20 @@ extension ConfigSnapshotReader { /// - defaultValue: The fallback value returned when the config value is missing or invalid. /// - fileID: The file ID where this call originates. Used for access reporting. /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: ConfigKey, - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - value( - forKey: key, - type: .string, - isSecret: isSecret, - default: defaultValue, - unwrap: { try cast($0.asString, type: Value.self, key: key) }, - wrap: { uncast($0) }, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = snapshot.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - - /// Synchronously gets a required config value for the given config key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let serverMode = try snapshot.requiredString(forKey: ["server", "mode"], as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The config key to look up. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( + /// - Returns: The config value if found and convertible, otherwise the default value. + public func string( forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, + default defaultValue: Value, fileID: String = #fileID, line: UInt = #line - ) throws -> Value { - try requiredValue( + ) -> Value { + value( forKey: key, type: .string, isSecret: isSecret, + default: defaultValue, unwrap: { try cast($0.asString, type: Value.self, key: key) }, wrap: { uncast($0) }, fileID: fileID, @@ -2193,18 +1106,17 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. + /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. /// The method throws an error if the value is missing or can't be converted to the expected type. /// /// ```swift - /// let logLevel = try snapshot.requiredString(forKey: "logging.level", as: LogLevel.self) + /// let serverMode = try snapshot.requiredString(forKey: ["server", "mode"], as: ServerMode.self) /// ``` /// /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. + /// - key: The config key to look up. /// - type: The type to convert the string value to. /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. /// - fileID: The file ID where this call originates. Used for access reporting. @@ -2212,17 +1124,18 @@ extension ConfigSnapshotReader { /// - Returns: The config value converted to the expected type. /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], + forKey key: ConfigKey, as type: Value.Type = Value.self, isSecret: Bool = false, fileID: String = #fileID, line: UInt = #line ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, + try requiredValue( + forKey: key, + type: .string, isSecret: isSecret, + unwrap: { try cast($0.asString, type: Value.self, key: key) }, + wrap: { uncast($0) }, fileID: fileID, line: line ) @@ -2262,40 +1175,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverModes = snapshot.stringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types. @@ -2334,44 +1213,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = snapshot.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -2407,41 +1248,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try snapshot.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, converting from string. /// /// Use this method to retrieve configuration values that can be converted from strings, @@ -2477,40 +1283,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. - /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverMode = snapshot.string(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result for string-convertible types. @@ -2549,44 +1321,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = snapshot.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. @@ -2622,41 +1356,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try snapshot.requiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings. @@ -2691,40 +1390,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverModes = snapshot.stringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types. @@ -2763,44 +1428,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = snapshot.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -2836,39 +1463,4 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try snapshot.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray>( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - } diff --git a/Sources/Configuration/ConfigSnapshotReader+methods.swift.gyb b/Sources/Configuration/ConfigSnapshotReader+methods.swift.gyb index e63723a..e8cd9aa 100644 --- a/Sources/Configuration/ConfigSnapshotReader+methods.swift.gyb +++ b/Sources/Configuration/ConfigSnapshotReader+methods.swift.gyb @@ -54,37 +54,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key. - /// - /// Use this method to retrieve optional configuration values using string-based keys. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let dbUrl = snapshot.string(forKey: "database.url") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func ${primitive_type["lowercase_name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> ${primitive_type["type"]}? { - ${primitive_type["lowercase_name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key, with a default fallback. /// /// Use this method when you need a guaranteed non-nil result. If the configuration @@ -121,41 +90,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given config key, providing a default fallback. - /// - /// Use this method when you need a guaranteed non-nil result. If the configuration - /// value is missing or can't be converted to the expected type, the default value - /// is returned instead. - /// - /// ```swift - /// let limit = snapshot.int(forKey: "api.rateLimit", default: 1000) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func ${primitive_type["lowercase_name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - default defaultValue: ${primitive_type["type"]}, - fileID: String = #fileID, - line: UInt = #line - ) -> ${primitive_type["type"]} { - ${primitive_type["lowercase_name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, throwing an error if it's missing. /// /// Use this method when a configuration value is mandatory for your application to function. @@ -189,38 +123,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, throwing an error if it's missing. - /// - /// Use this method when a configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let endpoint = try snapshot.requiredString(forKey: "service.endpoint") - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func required${primitive_type["name"]}( - forKey key: String, - context: [String: ConfigContextValue] = [:], - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> ${primitive_type["type"]} { - try required${primitive_type["name"]}( - forKey: keyDecoder.decode(key, context: context), - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end % for string_convertible_type in string_convertible_types: /// Synchronously gets a config value for the given config key, converting from string. @@ -258,40 +160,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key, converting from string. - /// - /// Use this method to retrieve configuration values that can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverMode = snapshot.string(forKey: "server.mode", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The value converted to the expected type if found and convertible, otherwise `nil`. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> Value? { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a config value for the given config key with default fallback, converting from string. /// /// Use this method when you need a guaranteed non-nil result for string-convertible types. @@ -330,44 +198,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a config value for the given string key with default fallback, converting from string. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevel = snapshot.string(forKey: "logging.level", as: LogLevel.self, default: .info) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback value returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value if found and convertible, otherwise the default value. - public func string( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: Value, - fileID: String = #fileID, - line: UInt = #line - ) -> Value { - string( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required config value for the given config key, converting from string. /// /// Use this method when a string-convertible configuration value is mandatory for your application to function. @@ -403,41 +233,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required config value for the given string key, converting from string. - /// - /// Use this method when a string-convertible configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let logLevel = try snapshot.requiredString(forKey: "logging.level", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The type to convert the string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config value converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredString( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> Value { - try requiredString( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key, converting from strings. /// /// Use this method to retrieve configuration arrays where each element can be converted from strings. @@ -472,40 +267,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key, converting from strings. - /// - /// Use this method to retrieve configuration arrays where each element can be converted from strings. - /// If the value doesn't exist or can't be converted to the expected type, the method returns `nil`. - /// - /// ```swift - /// let serverModes = snapshot.stringArray(forKey: "server.allowedModes", as: ServerMode.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: An array of values converted to the expected type if found and convertible, otherwise `nil`. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) -> [Value]? { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - /// Synchronously gets an array of config values for the given config key with default fallback, converting from strings. /// /// Use this method when you need a guaranteed non-nil result for string-convertible array types. @@ -544,44 +305,6 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets an array of config values for the given string key with default fallback, converting from strings. - /// - /// Use this method when you need a guaranteed non-nil result for string-convertible array types. - /// If the configuration value is missing or can't be converted to the expected type, - /// the default value is returned instead. - /// - /// ```swift - /// let logLevels = snapshot.stringArray(forKey: "logging.enabledLevels", as: LogLevel.self, default: [.info]) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - defaultValue: The fallback array returned when the config value is missing or invalid. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array if found and convertible, otherwise the default array. - public func stringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - default defaultValue: [Value], - fileID: String = #fileID, - line: UInt = #line - ) -> [Value] { - stringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - default: defaultValue, - fileID: fileID, - line: line - ) - } - /// Synchronously gets a required array of config values for the given config key, converting from strings. /// /// Use this method when a string-convertible array configuration value is mandatory for your application to function. @@ -617,40 +340,5 @@ extension ConfigSnapshotReader { ) } - /// Synchronously gets a required array of config values for the given string key, converting from strings. - /// - /// Use this method when a string-convertible array configuration value is mandatory for your application to function. - /// The method throws an error if the value is missing or can't be converted to the expected type. - /// - /// ```swift - /// let requiredLevels = try snapshot.requiredStringArray(forKey: "logging.enabledLevels", as: LogLevel.self) - /// ``` - /// - /// - Parameters: - /// - key: The string representation of the config key to look up. - /// - context: Additional context used for key resolution. - /// - type: The element type to convert each string value to. - /// - isSecret: Whether the value should be treated as secret for logging and debugging purposes. - /// - fileID: The file ID where this call originates. Used for access reporting. - /// - line: The line number where this call originates. Used for access reporting. - /// - Returns: The config array converted to the expected type. - /// - Throws: If the value is missing, or a conversion error if the value can't be converted to the expected type. - public func requiredStringArray( - forKey key: String, - context: [String: ConfigContextValue] = [:], - as type: Value.Type = Value.self, - isSecret: Bool = false, - fileID: String = #fileID, - line: UInt = #line - ) throws -> [Value] { - try requiredStringArray( - forKey: keyDecoder.decode(key, context: context), - as: type, - isSecret: isSecret, - fileID: fileID, - line: line - ) - } - % end } diff --git a/Sources/Configuration/ConfigSnapshotReader.swift b/Sources/Configuration/ConfigSnapshotReader.swift index f3820a9..9b356ea 100644 --- a/Sources/Configuration/ConfigSnapshotReader.swift +++ b/Sources/Configuration/ConfigSnapshotReader.swift @@ -73,24 +73,7 @@ import Synchronization /// /// ```swift /// let httpTimeout = snapshotReader.int( -/// forKey: "http.timeout", -/// context: ["upstream": "example.com"], -/// default: 60 -/// ) -/// ``` -/// -/// ### Key decoding -/// -/// By default, the snapshot reader uses the key decoder from the original config reader, but you can -/// provide a different one when creating a scoped reader: -/// -/// ```swift -/// let scopedReader = snapshotReader.scoped( -/// to: "http", -/// keyDecoderOverride: .colonSeparated -/// ) -/// let timeout = scopedReader.int( -/// forKey: "http:timeout", +/// forKey: ConfigKey("http.timeout", context: ["upstream": "example.com"]), /// default: 60 /// ) /// ``` @@ -164,11 +147,6 @@ public struct ConfigSnapshotReader: Sendable { /// from this one. final class Storage: Sendable { - /// The key decoder that the library uses to interpret string keys. - /// - /// For example, turns `foo.bar.baz` into `["foo", "bar", "baz"]`. - let keyDecoder: any ConfigKeyDecoder - /// The underlying multi snapshot. let snapshot: MultiSnapshot @@ -177,15 +155,12 @@ public struct ConfigSnapshotReader: Sendable { /// Creates a storage instance. /// - Parameters: - /// - keyDecoder: The key decoder used by methods that take string keys. /// - snapshot: The underlying multi snapshot. /// - accessReporter: The reporter of access events. init( - keyDecoder: some ConfigKeyDecoder, snapshot: MultiSnapshot, accessReporter: (any AccessReporter)? ) { - self.keyDecoder = keyDecoder self.snapshot = snapshot self.accessReporter = accessReporter } @@ -194,11 +169,6 @@ public struct ConfigSnapshotReader: Sendable { /// The underlying storage that is shared with any transitive child readers created from this one. private var storage: Storage - /// The key decoder the library uses to interpret string keys. - var keyDecoder: any ConfigKeyDecoder { - storage.keyDecoder - } - /// The underlying multi snapshot. private var snapshot: MultiSnapshot { storage.snapshot @@ -226,21 +196,10 @@ public struct ConfigSnapshotReader: Sendable { /// - Parameters: /// - scopedKey: The key to append to the current key prefix. /// - parent: The parent reader from which to create a scoped reader. - /// - keyDecoderOverride: A key decoder that replaces the original key decoder. - private init(scopedKey: ConfigKey, parent: ConfigSnapshotReader, keyDecoderOverride: (any ConfigKeyDecoder)?) { - let storage: Storage - if let keyDecoderOverride { - storage = .init( - keyDecoder: keyDecoderOverride, - snapshot: parent.storage.snapshot, - accessReporter: parent.storage.accessReporter - ) - } else { - storage = parent.storage - } + private init(scopedKey: ConfigKey, parent: ConfigSnapshotReader) { self.init( keyPrefix: parent.keyPrefix.appending(scopedKey), - storage: storage + storage: parent.storage ) } @@ -253,44 +212,14 @@ public struct ConfigSnapshotReader: Sendable { /// let timeout = httpConfig.int(forKey: "timeout") // Reads from "client.http.timeout" in the snapshot /// ``` /// - /// - Parameters: - /// - configKey: The key to append to the current key prefix. - /// - keyDecoderOverride: A key decoder that replaces the original key decoder. + /// - Parameters configKey: The key to append to the current key prefix. /// - Returns: A reader for accessing scoped values. - public func scoped(to configKey: ConfigKey, keyDecoderOverride: (any ConfigKeyDecoder)? = nil) + public func scoped(to configKey: ConfigKey) -> ConfigSnapshotReader { ConfigSnapshotReader( scopedKey: configKey, - parent: self, - keyDecoderOverride: keyDecoderOverride - ) - } - - /// Returns a scoped reader by appending the provided key to the current key prefix. - /// - /// Use this method to create a reader that accesses a subset of the configuration, - /// using a string key that will be decoded according to the reader's key decoder. - /// - /// ```swift - /// let httpConfig = snapshotReader.scoped(to: "http.client") - /// let timeout = httpConfig.int(forKey: "timeout") // Reads from "http.client.timeout" in the snapshot - /// ``` - /// - /// - Parameters: - /// - key: The key to append to the current key prefix. - /// - context: Additional config context for the key. - /// - keyDecoderOverride: A key decoder that replaces the original key decoder. - /// - Returns: A reader for accessing scoped values. - public func scoped( - to key: String, - context: [String: ConfigContextValue] = [:], - keyDecoderOverride: (any ConfigKeyDecoder)? = nil - ) -> ConfigSnapshotReader { - ConfigSnapshotReader( - scopedKey: (keyDecoderOverride ?? keyDecoder).decode(key, context: context), - parent: self, - keyDecoderOverride: keyDecoderOverride + parent: self ) } } @@ -324,7 +253,6 @@ extension ConfigReader { let snapshotReader = ConfigSnapshotReader( keyPrefix: keyPrefix, storage: .init( - keyDecoder: keyDecoder, snapshot: multiSnapshot, accessReporter: accessReporter ) @@ -370,7 +298,6 @@ extension ConfigReader { ConfigSnapshotReader( keyPrefix: keyPrefix, storage: .init( - keyDecoder: keyDecoder, snapshot: multiSnapshot, accessReporter: accessReporter ) diff --git a/Sources/Configuration/Documentation.docc/Documentation.md b/Sources/Configuration/Documentation.docc/Documentation.md index 273f10a..a4aa9bb 100644 --- a/Sources/Configuration/Documentation.docc/Documentation.md +++ b/Sources/Configuration/Documentation.docc/Documentation.md @@ -291,7 +291,7 @@ Read for details on how to receive updates as co #### Namespacing and scoped readers The built-in namespacing of ``ConfigKey`` interprets `"http.timeout"` as an array of two components: `"http"` and `"timeout"`. -The following example uses ``ConfigReader/scoped(to:context:keyDecoderOverride:)`` to create a namespaced reader with the key `"http"`, to allow reads to use the shorter key `"timeout"`: +The following example uses ``ConfigReader/scoped(to:)`` to create a namespaced reader with the key `"http"`, to allow reads to use the shorter key `"timeout"`: Consider the following JSON configuration: @@ -373,24 +373,6 @@ try config.withSnapshot { snapshot in } ``` -#### Custom key syntax - -Customizable shorthand key syntax using ``ConfigKeyDecoder`` allows namespacing using not just the default dot-separated `http.timeout`, but any custom convention, such as `http::timeout`: - -```swift -// Create a custom key decoder that uses double-colon separator -let doubleColonDecoder = SeparatorKeyDecoder(separator: "::") - -// Use the keyDecoder parameter when creating the config reader -let config = ConfigReader( - provider: EnvironmentVariablesProvider(), - keyDecoder: doubleColonDecoder -) - -// Now you can use double-colon syntax in your keys -let timeout = config.int(forKey: "http::timeout", default: 60) -``` - #### Extensible ecosystem Any package can implement a ``ConfigProvider``, making the ecosystem extensible for custom configuration sources. @@ -441,9 +423,7 @@ Any package can implement a ``ConfigProvider``, making the ecosystem extensible - ``AbsoluteConfigKey`` - ``ConfigContextValue`` - ``ConfigKeyEncoder`` -- ``ConfigKeyDecoder`` - ``SeparatorKeyEncoder`` -- ``SeparatorKeyDecoder`` - ``DirectoryFileKeyEncoder`` ### Troubleshooting and access reporting diff --git a/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md b/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md index a13aea5..ac415b9 100644 --- a/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md +++ b/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md @@ -8,13 +8,11 @@ Check out some techniques to debug unexpected issues and to increase visibility If your configuration values aren't being read correctly, check: -1. **Key formatting**: Make sure the key format matches your `ConfigKeyDecoder`. The default is dot-notation (for example, `database.url`). +1. **Environment variable naming**: When using `EnvironmentVariablesProvider`, keys are automatically converted to uppercase with dots replaced by underscores. For example, `database.url` becomes `DATABASE_URL`. -2. **Environment variable naming**: When using `EnvironmentVariablesProvider`, keys are automatically converted to uppercase with dots replaced by underscores. For example, `database.url` becomes `DATABASE_URL`. +2. **Provider ordering**: When using multiple providers, remember they're checked in order, and the first one that returns a value wins. -3. **Provider ordering**: When using multiple providers, remember they're checked in order, and the first one that returns a value wins. - -4. **Debug with an access reporter**: Use the access reporting feature to see which keys are being queried and what values (if any) are being returned. See the next section for details. +3. **Debug with an access reporter**: Use the access reporting feature to see which keys are being queried and what values (if any) are being returned. See the next section for details. For guidance on selecting the right configuration access patterns and reader methods, check out and . diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigKey.md b/Sources/Configuration/Documentation.docc/Reference/ConfigKey.md index ff778e0..97b617c 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigKey.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigKey.md @@ -4,7 +4,8 @@ ### Creating a configuration key -- ``init(_:context:)`` +- ``init(_:context:)-(String,_)`` +- ``init(_:context:)-([String],_)`` ### Inspecting a configuration key diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigKeyDecoder.md b/Sources/Configuration/Documentation.docc/Reference/ConfigKeyDecoder.md deleted file mode 100644 index 24c0e29..0000000 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigKeyDecoder.md +++ /dev/null @@ -1,12 +0,0 @@ -# ``Configuration/ConfigKeyDecoder`` - -## Topics - -### Built-in key decoders - -- ``colonSeparated`` -- ``dotSeparated`` - -### Decoding keys - -- ``decode(_:context:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigProvider.md b/Sources/Configuration/Documentation.docc/Reference/ConfigProvider.md index 37b4455..0505db7 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigProvider.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigProvider.md @@ -15,4 +15,3 @@ - ``ConfigProvider/watchSnapshotFromSnapshot(updatesHandler:)`` - ``ConfigProvider/mapKeys(_:)`` - ``ConfigProvider/prefixKeys(with:)`` -- ``ConfigProvider/prefixKeys(with:context:keyDecoder:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Fetch.md b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Fetch.md index dde2ab0..f8c012c 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Fetch.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Fetch.md @@ -9,12 +9,6 @@ - ``ConfigReader/fetchString(forKey:as:isSecret:fileID:line:)-2zxxs`` - ``ConfigReader/fetchString(forKey:as:isSecret:default:fileID:line:)-9vhmw`` - ``ConfigReader/fetchString(forKey:as:isSecret:default:fileID:line:)-7hxpy`` -- ``ConfigReader/fetchString(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchString(forKey:context:as:isSecret:fileID:line:)-hkv9`` -- ``ConfigReader/fetchString(forKey:context:as:isSecret:fileID:line:)-4zh0u`` -- ``ConfigReader/fetchString(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchString(forKey:context:as:isSecret:default:fileID:line:)-2u7bm`` -- ``ConfigReader/fetchString(forKey:context:as:isSecret:default:fileID:line:)-uhwf`` ### Asynchronously fetching lists of string values - ``ConfigReader/fetchStringArray(forKey:isSecret:fileID:line:)`` @@ -23,106 +17,70 @@ - ``ConfigReader/fetchStringArray(forKey:isSecret:default:fileID:line:)`` - ``ConfigReader/fetchStringArray(forKey:as:isSecret:default:fileID:line:)-1fcex`` - ``ConfigReader/fetchStringArray(forKey:as:isSecret:default:fileID:line:)-3te90`` -- ``ConfigReader/fetchStringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchStringArray(forKey:context:as:isSecret:fileID:line:)-5a8op`` -- ``ConfigReader/fetchStringArray(forKey:context:as:isSecret:fileID:line:)-3pt8l`` -- ``ConfigReader/fetchStringArray(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchStringArray(forKey:context:as:isSecret:default:fileID:line:)-4qojv`` -- ``ConfigReader/fetchStringArray(forKey:context:as:isSecret:default:fileID:line:)-95ldu`` ### Asynchronously fetching required string values - ``ConfigReader/fetchRequiredString(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchRequiredString(forKey:as:isSecret:fileID:line:)-79md3`` - ``ConfigReader/fetchRequiredString(forKey:as:isSecret:fileID:line:)-e16l`` -- ``ConfigReader/fetchRequiredString(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredString(forKey:context:as:isSecret:fileID:line:)-6oi3w`` -- ``ConfigReader/fetchRequiredString(forKey:context:as:isSecret:fileID:line:)-3c6et`` ### Asynchronously fetching required lists of string values - ``ConfigReader/fetchRequiredStringArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchRequiredStringArray(forKey:as:isSecret:fileID:line:)-6es6t`` - ``ConfigReader/fetchRequiredStringArray(forKey:as:isSecret:fileID:line:)-1bf0t`` -- ``ConfigReader/fetchRequiredStringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredStringArray(forKey:context:as:isSecret:fileID:line:)-7gx39`` -- ``ConfigReader/fetchRequiredStringArray(forKey:context:as:isSecret:fileID:line:)-3ajdb`` ### Asynchronously fetching Boolean values - ``ConfigReader/fetchBool(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchBool(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchBool(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchBool(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required Boolean values - ``ConfigReader/fetchRequiredBool(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredBool(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching lists of Boolean values - ``ConfigReader/fetchBoolArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchBoolArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchBoolArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchBoolArray(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required lists of Boolean values - ``ConfigReader/fetchRequiredBoolArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredBoolArray(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching integer values - ``ConfigReader/fetchInt(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchInt(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchInt(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchInt(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required integer values - ``ConfigReader/fetchRequiredInt(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredInt(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching lists of integer values - ``ConfigReader/fetchIntArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchIntArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchIntArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchIntArray(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required lists of integer values - ``ConfigReader/fetchRequiredIntArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredIntArray(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching double values - ``ConfigReader/fetchDouble(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchDouble(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchDouble(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchDouble(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required double values - ``ConfigReader/fetchRequiredDouble(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredDouble(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching lists of double values - ``ConfigReader/fetchDoubleArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchDoubleArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchDoubleArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchDoubleArray(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required lists of double values - ``ConfigReader/fetchRequiredDoubleArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredDoubleArray(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching bytes - ``ConfigReader/fetchBytes(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchBytes(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchBytes(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchBytes(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required bytes - ``ConfigReader/fetchRequiredBytes(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredBytes(forKey:context:isSecret:fileID:line:)`` ### Asynchronously fetching lists of byte chunks - ``ConfigReader/fetchByteChunkArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/fetchByteChunkArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/fetchByteChunkArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/fetchByteChunkArray(forKey:context:isSecret:default:fileID:line:)`` ### Asynchronously fetching required lists of byte chunks - ``ConfigReader/fetchRequiredByteChunkArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/fetchRequiredByteChunkArray(forKey:context:isSecret:fileID:line:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Get.md b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Get.md index 614e845..24b6f37 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Get.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Get.md @@ -9,12 +9,6 @@ - ``ConfigReader/string(forKey:as:isSecret:fileID:line:)-4oust`` - ``ConfigReader/string(forKey:as:isSecret:default:fileID:line:)-9xr3c`` - ``ConfigReader/string(forKey:as:isSecret:default:fileID:line:)-1sqv7`` -- ``ConfigReader/string(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/string(forKey:context:as:isSecret:fileID:line:)-5xayt`` -- ``ConfigReader/string(forKey:context:as:isSecret:fileID:line:)-4vfyt`` -- ``ConfigReader/string(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigReader/string(forKey:context:as:isSecret:default:fileID:line:)-9j7c2`` -- ``ConfigReader/string(forKey:context:as:isSecret:default:fileID:line:)-7r5wf`` ### Synchronously reading lists of string values - ``ConfigReader/stringArray(forKey:isSecret:fileID:line:)`` @@ -23,105 +17,69 @@ - ``ConfigReader/stringArray(forKey:isSecret:default:fileID:line:)`` - ``ConfigReader/stringArray(forKey:as:isSecret:default:fileID:line:)-7tit4`` - ``ConfigReader/stringArray(forKey:as:isSecret:default:fileID:line:)-139vb`` -- ``ConfigReader/stringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/stringArray(forKey:context:as:isSecret:fileID:line:)-74wq0`` -- ``ConfigReader/stringArray(forKey:context:as:isSecret:fileID:line:)-47d8x`` -- ``ConfigReader/stringArray(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigReader/stringArray(forKey:context:as:isSecret:default:fileID:line:)-6pczv`` -- ``ConfigReader/stringArray(forKey:context:as:isSecret:default:fileID:line:)-2dywu`` ### Synchronously reading required string values - ``ConfigReader/requiredString(forKey:isSecret:fileID:line:)`` - ``ConfigReader/requiredString(forKey:as:isSecret:fileID:line:)-2fljl`` - ``ConfigReader/requiredString(forKey:as:isSecret:fileID:line:)-15z38`` -- ``ConfigReader/requiredString(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/requiredString(forKey:context:as:isSecret:fileID:line:)-6xsfl`` -- ``ConfigReader/requiredString(forKey:context:as:isSecret:fileID:line:)-5ayhp`` ### Synchronously reading required lists of string values - ``ConfigReader/requiredStringArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/requiredStringArray(forKey:as:isSecret:fileID:line:)-97pcp`` - ``ConfigReader/requiredStringArray(forKey:as:isSecret:fileID:line:)-pxel`` -- ``ConfigReader/requiredStringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/requiredStringArray(forKey:context:as:isSecret:fileID:line:)-12i47`` -- ``ConfigReader/requiredStringArray(forKey:context:as:isSecret:fileID:line:)-20kv2`` ### Synchronously reading Boolean values - ``ConfigReader/bool(forKey:isSecret:fileID:line:)`` - ``ConfigReader/bool(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/bool(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/bool(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required Boolean values - ``ConfigReader/requiredBool(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredBool(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of Boolean values - ``ConfigReader/boolArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/boolArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/boolArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/boolArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of Boolean values - ``ConfigReader/requiredBoolArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredBoolArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading integer values - ``ConfigReader/int(forKey:isSecret:fileID:line:)`` - ``ConfigReader/int(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/int(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/int(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required integer values - ``ConfigReader/requiredInt(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredInt(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of integer values - ``ConfigReader/intArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/intArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/intArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/intArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of integer values - ``ConfigReader/requiredIntArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredIntArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading double values - ``ConfigReader/double(forKey:isSecret:fileID:line:)`` - ``ConfigReader/double(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/double(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/double(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required double values - ``ConfigReader/requiredDouble(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredDouble(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of double values - ``ConfigReader/doubleArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/doubleArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/doubleArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/doubleArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of double values - ``ConfigReader/requiredDoubleArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredDoubleArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading bytes - ``ConfigReader/bytes(forKey:isSecret:fileID:line:)`` - ``ConfigReader/bytes(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/bytes(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/bytes(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required bytes - ``ConfigReader/requiredBytes(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredBytes(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading collections of byte chunks - ``ConfigReader/byteChunkArray(forKey:isSecret:fileID:line:)`` - ``ConfigReader/byteChunkArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigReader/byteChunkArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigReader/byteChunkArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required collections of byte chunks - ``ConfigReader/requiredByteChunkArray(forKey:isSecret:fileID:line:)`` -- ``ConfigReader/requiredByteChunkArray(forKey:context:isSecret:fileID:line:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Watch.md b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Watch.md index 6abb641..4ac7b8e 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Watch.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigReader-Watch.md @@ -9,20 +9,11 @@ - ``ConfigReader/watchString(forKey:isSecret:default:fileID:line:updatesHandler:)`` - ``ConfigReader/watchString(forKey:as:isSecret:default:fileID:line:updatesHandler:)-6m0yu`` - ``ConfigReader/watchString(forKey:as:isSecret:default:fileID:line:updatesHandler:)-6dpc3`` -- ``ConfigReader/watchString(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchString(forKey:context:as:isSecret:fileID:line:updatesHandler:)-34wbx`` -- ``ConfigReader/watchString(forKey:context:as:isSecret:fileID:line:updatesHandler:)-549xr`` -- ``ConfigReader/watchString(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchString(forKey:context:as:isSecret:default:fileID:line:updatesHandler:)-9u7vf`` -- ``ConfigReader/watchString(forKey:context:as:isSecret:default:fileID:line:updatesHandler:)-1ofiv`` ### Watching required string values - ``ConfigReader/watchRequiredString(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchRequiredString(forKey:as:isSecret:fileID:line:updatesHandler:)-86ot1`` - ``ConfigReader/watchRequiredString(forKey:as:isSecret:fileID:line:updatesHandler:)-3lrs7`` -- ``ConfigReader/watchRequiredString(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredString(forKey:context:as:isSecret:fileID:line:updatesHandler:)-77978`` -- ``ConfigReader/watchRequiredString(forKey:context:as:isSecret:fileID:line:updatesHandler:)-138o2`` ### Watching lists of string values - ``ConfigReader/watchStringArray(forKey:isSecret:fileID:line:updatesHandler:)`` @@ -31,98 +22,65 @@ - ``ConfigReader/watchStringArray(forKey:isSecret:default:fileID:line:updatesHandler:)`` - ``ConfigReader/watchStringArray(forKey:as:isSecret:default:fileID:line:updatesHandler:)-59de`` - ``ConfigReader/watchStringArray(forKey:as:isSecret:default:fileID:line:updatesHandler:)-8nsil`` -- ``ConfigReader/watchStringArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchStringArray(forKey:context:as:isSecret:fileID:line:updatesHandler:)-5occx`` -- ``ConfigReader/watchStringArray(forKey:context:as:isSecret:fileID:line:updatesHandler:)-30hf0`` -- ``ConfigReader/watchStringArray(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchStringArray(forKey:context:as:isSecret:default:fileID:line:updatesHandler:)-4txm0`` -- ``ConfigReader/watchStringArray(forKey:context:as:isSecret:default:fileID:line:updatesHandler:)-3eipe`` ### Watching required lists of string values - ``ConfigReader/watchRequiredStringArray(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchRequiredStringArray(forKey:as:isSecret:fileID:line:updatesHandler:)-3whiy`` - ``ConfigReader/watchRequiredStringArray(forKey:as:isSecret:fileID:line:updatesHandler:)-4zyyq`` -- ``ConfigReader/watchRequiredStringArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredStringArray(forKey:context:as:isSecret:fileID:line:updatesHandler:)-97r4l`` -- ``ConfigReader/watchRequiredStringArray(forKey:context:as:isSecret:fileID:line:updatesHandler:)-4jcy3`` ### Watching Boolean values - ``ConfigReader/watchBool(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchBool(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBool(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBool(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required Boolean values - ``ConfigReader/watchRequiredBool(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredBool(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching lists Boolean values - ``ConfigReader/watchBoolArray(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchBoolArray(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBoolArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBoolArray(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required lists Boolean values - ``ConfigReader/watchRequiredBoolArray(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredBoolArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching integer values - ``ConfigReader/watchInt(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchInt(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchInt(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchInt(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required integer values - ``ConfigReader/watchRequiredInt(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredInt(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching lists of integer values - ``ConfigReader/watchIntArray(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchIntArray(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchIntArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchIntArray(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required lists of integer values - ``ConfigReader/watchRequiredIntArray(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredIntArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching double values - ``ConfigReader/watchDouble(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchDouble(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchDouble(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchDouble(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required double values - ``ConfigReader/watchRequiredDouble(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredDouble(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching lists of double values - ``ConfigReader/watchDoubleArray(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchDoubleArray(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchDoubleArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchDoubleArray(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required double of integer values - ``ConfigReader/watchRequiredDoubleArray(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredDoubleArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching bytes - ``ConfigReader/watchBytes(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchBytes(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBytes(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchBytes(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required bytes - ``ConfigReader/watchRequiredBytes(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredBytes(forKey:context:isSecret:fileID:line:updatesHandler:)`` ### Watching lists of byte chunks - ``ConfigReader/watchByteChunkArray(forKey:isSecret:fileID:line:updatesHandler:)`` - ``ConfigReader/watchByteChunkArray(forKey:isSecret:default:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchByteChunkArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchByteChunkArray(forKey:context:isSecret:default:fileID:line:updatesHandler:)`` ### Watching required lists of byte chunks - ``ConfigReader/watchRequiredByteChunkArray(forKey:isSecret:fileID:line:updatesHandler:)`` -- ``ConfigReader/watchRequiredByteChunkArray(forKey:context:isSecret:fileID:line:updatesHandler:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigReader.md b/Sources/Configuration/Documentation.docc/Reference/ConfigReader.md index b5e3195..ff31a07 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigReader.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigReader.md @@ -4,12 +4,11 @@ ### Creating config readers -- ``ConfigReader/init(keyDecoder:provider:accessReporter:)`` -- ``ConfigReader/init(keyDecoder:providers:accessReporter:)`` +- ``ConfigReader/init(provider:accessReporter:)`` +- ``ConfigReader/init(providers:accessReporter:)`` ### Retrieving a scoped config reader -- ``ConfigReader/scoped(to:context:keyDecoderOverride:)`` -- ``ConfigReader/scoped(to:keyDecoderOverride:)`` +- ``ConfigReader/scoped(to:)`` ### Reading from a snapshot - ``ConfigReader/withSnapshot(_:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/ConfigSnapshotReader.md b/Sources/Configuration/Documentation.docc/Reference/ConfigSnapshotReader.md index 327dd20..4236575 100644 --- a/Sources/Configuration/Documentation.docc/Reference/ConfigSnapshotReader.md +++ b/Sources/Configuration/Documentation.docc/Reference/ConfigSnapshotReader.md @@ -7,8 +7,7 @@ - ``ConfigReader/watchSnapshot(fileID:line:updatesHandler:)`` ### Namespacing -- ``ConfigSnapshotReader/scoped(to:context:keyDecoderOverride:)`` -- ``ConfigSnapshotReader/scoped(to:keyDecoderOverride:)`` +- ``ConfigSnapshotReader/scoped(to:)`` ### Synchronously reading string values - ``ConfigSnapshotReader/string(forKey:isSecret:fileID:line:)`` @@ -17,12 +16,6 @@ - ``ConfigSnapshotReader/string(forKey:as:isSecret:fileID:line:)-7bpif`` - ``ConfigSnapshotReader/string(forKey:as:isSecret:default:fileID:line:)-fzpe`` - ``ConfigSnapshotReader/string(forKey:as:isSecret:default:fileID:line:)-2mphx`` -- ``ConfigSnapshotReader/string(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/string(forKey:context:as:isSecret:fileID:line:)-4xl9h`` -- ``ConfigSnapshotReader/string(forKey:context:as:isSecret:fileID:line:)-2bx31`` -- ``ConfigSnapshotReader/string(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/string(forKey:context:as:isSecret:default:fileID:line:)-9zl96`` -- ``ConfigSnapshotReader/string(forKey:context:as:isSecret:default:fileID:line:)-3azme`` ### Synchronously reading lists of string values - ``ConfigSnapshotReader/stringArray(forKey:isSecret:fileID:line:)`` @@ -31,105 +24,69 @@ - ``ConfigSnapshotReader/stringArray(forKey:isSecret:default:fileID:line:)`` - ``ConfigSnapshotReader/stringArray(forKey:as:isSecret:default:fileID:line:)-8n896`` - ``ConfigSnapshotReader/stringArray(forKey:as:isSecret:default:fileID:line:)-yx0h`` -- ``ConfigSnapshotReader/stringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/stringArray(forKey:context:as:isSecret:fileID:line:)-2cmxo`` -- ``ConfigSnapshotReader/stringArray(forKey:context:as:isSecret:fileID:line:)-141zx`` -- ``ConfigSnapshotReader/stringArray(forKey:context:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/stringArray(forKey:context:as:isSecret:default:fileID:line:)-2hjcv`` -- ``ConfigSnapshotReader/stringArray(forKey:context:as:isSecret:default:fileID:line:)-5dkbi`` ### Synchronously reading required string values - ``ConfigSnapshotReader/requiredString(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/requiredString(forKey:as:isSecret:fileID:line:)-85qdd`` - ``ConfigSnapshotReader/requiredString(forKey:as:isSecret:fileID:line:)-3iy7q`` -- ``ConfigSnapshotReader/requiredString(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredString(forKey:context:as:isSecret:fileID:line:)-8cx83`` -- ``ConfigSnapshotReader/requiredString(forKey:context:as:isSecret:fileID:line:)-1056`` ### Synchronously reading required lists of string values - ``ConfigSnapshotReader/requiredStringArray(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/requiredStringArray(forKey:as:isSecret:fileID:line:)-4nuew`` - ``ConfigSnapshotReader/requiredStringArray(forKey:as:isSecret:fileID:line:)-4pyhg`` -- ``ConfigSnapshotReader/requiredStringArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredStringArray(forKey:context:as:isSecret:fileID:line:)-4e338`` -- ``ConfigSnapshotReader/requiredStringArray(forKey:context:as:isSecret:fileID:line:)-5q0ew`` ### Synchronously reading Boolean values - ``ConfigSnapshotReader/bool(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/bool(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/bool(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/bool(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required Boolean values - ``ConfigSnapshotReader/requiredBool(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredBool(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of Boolean values - ``ConfigSnapshotReader/boolArray(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/boolArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/boolArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/boolArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of Boolean values - ``ConfigSnapshotReader/requiredBoolArray(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredBoolArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading integer values - ``ConfigSnapshotReader/int(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/int(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/int(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/int(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required integer values - ``ConfigSnapshotReader/requiredInt(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredInt(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of integer values - ``ConfigSnapshotReader/intArray(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/intArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/intArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/intArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of integer values - ``ConfigSnapshotReader/requiredIntArray(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredIntArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading double values - ``ConfigSnapshotReader/double(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/double(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/double(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/double(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required double values - ``ConfigSnapshotReader/requiredDouble(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredDouble(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading lists of double values - ``ConfigSnapshotReader/doubleArray(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/doubleArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/doubleArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/doubleArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required lists of double values - ``ConfigSnapshotReader/requiredDoubleArray(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredDoubleArray(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading bytes - ``ConfigSnapshotReader/bytes(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/bytes(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/bytes(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/bytes(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required bytes - ``ConfigSnapshotReader/requiredBytes(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredBytes(forKey:context:isSecret:fileID:line:)`` ### Synchronously reading collections of byte chunks - ``ConfigSnapshotReader/byteChunkArray(forKey:isSecret:fileID:line:)`` - ``ConfigSnapshotReader/byteChunkArray(forKey:isSecret:default:fileID:line:)`` -- ``ConfigSnapshotReader/byteChunkArray(forKey:context:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/byteChunkArray(forKey:context:isSecret:default:fileID:line:)`` ### Synchronously reading required collections of byte chunks - ``ConfigSnapshotReader/requiredByteChunkArray(forKey:isSecret:fileID:line:)`` -- ``ConfigSnapshotReader/requiredByteChunkArray(forKey:context:isSecret:fileID:line:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/InMemoryProvider.md b/Sources/Configuration/Documentation.docc/Reference/InMemoryProvider.md index e1f656c..edcf21b 100644 --- a/Sources/Configuration/Documentation.docc/Reference/InMemoryProvider.md +++ b/Sources/Configuration/Documentation.docc/Reference/InMemoryProvider.md @@ -5,4 +5,3 @@ ### Creating an in-memory provider - ``init(name:values:)`` -- ``init(name:values:keyDecoder:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/MutableMemoryProvider.md b/Sources/Configuration/Documentation.docc/Reference/MutableMemoryProvider.md index 78ab8e0..5aa1e6a 100644 --- a/Sources/Configuration/Documentation.docc/Reference/MutableMemoryProvider.md +++ b/Sources/Configuration/Documentation.docc/Reference/MutableMemoryProvider.md @@ -5,9 +5,7 @@ ### Creating a mutable in-memory provider - ``init(name:initialValues:)`` -- ``init(name:initialValues:keyDecoder:)`` ### Updating values in a mutable in-memory provider - ``setValue(_:forKey:)`` -- ``setValue(_:forKey:context:keyDecoder:)`` diff --git a/Sources/Configuration/Documentation.docc/Reference/SeparatorKeyDecoder.md b/Sources/Configuration/Documentation.docc/Reference/SeparatorKeyDecoder.md deleted file mode 100644 index 98774ce..0000000 --- a/Sources/Configuration/Documentation.docc/Reference/SeparatorKeyDecoder.md +++ /dev/null @@ -1,3 +0,0 @@ -# ``Configuration/SeparatorKeyDecoder`` - -## Topics diff --git a/Sources/Configuration/KeyCoders/CLIKeyEncoder.swift b/Sources/Configuration/KeyCoders/CLIKeyEncoder.swift index 35108bc..7043556 100644 --- a/Sources/Configuration/KeyCoders/CLIKeyEncoder.swift +++ b/Sources/Configuration/KeyCoders/CLIKeyEncoder.swift @@ -42,6 +42,7 @@ import Foundation /// // Multi-level hierarchy /// encoder.encode(["app", "database", "connectionPool", "maxSize"]) // "--app-database-connection-pool-max-size" /// ``` +@available(Configuration 1.0, *) internal struct CLIKeyEncoder { /// Converts a camelCase string to dash-case. @@ -81,6 +82,7 @@ internal struct CLIKeyEncoder { } } +@available(Configuration 1.0, *) extension CLIKeyEncoder: ConfigKeyEncoder { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation func encode(_ key: AbsoluteConfigKey) -> String { diff --git a/Sources/Configuration/KeyCoders/ConfigKeyDecoder.swift b/Sources/Configuration/KeyCoders/ConfigKeyDecoder.swift deleted file mode 100644 index b3f2c93..0000000 --- a/Sources/Configuration/KeyCoders/ConfigKeyDecoder.swift +++ /dev/null @@ -1,63 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftConfiguration open source project -// -// Copyright (c) 2025 Apple Inc. and the SwiftConfiguration project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftConfiguration project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -/// A protocol for decoding string representations into structured configuration keys. -/// -/// Key decoders transform flat string keys (like those found in environment variables -/// or configuration files) into hierarchical ``ConfigKey`` instances. This allows -/// configuration providers to work with different key naming conventions while -/// maintaining a consistent internal representation. -/// -/// ## Usage -/// -/// Implement this protocol to create custom key decoding strategies: -/// -/// ```swift -/// struct CustomKeyDecoder: ConfigKeyDecoder { -/// func decode(_ string: String, context: [String: ConfigContextValue]) -> ConfigKey { -/// let components = string.split(separator: "__").map(String.init) -/// return ConfigKey(components: components, context: context) -/// } -/// } -/// ``` -/// -/// ## Common implementations -/// -/// The framework provides several built-in key decoders: -/// - ``SeparatorKeyDecoder`` - Splits keys using a separator character -/// -/// ## See also -/// -/// - ``ConfigKeyEncoder`` - For encoding keys back to strings -/// - ``ConfigKey`` - The structured key representation -public protocol ConfigKeyDecoder: Sendable { - - /// Decodes a string representation into a structured configuration key. - /// - /// This method transforms a flat string key into a hierarchical ``ConfigKey`` - /// by parsing the string according to the decoder's specific strategy. The context - /// provides additional information that may influence the decoding process. - /// - /// ```swift - /// let decoder = SeparatorKeyDecoder(separator: ".") - /// let key = decoder.decode("database.host", context: context) - /// // Results in ConfigKey with components ["database", "host"] - /// ``` - /// - /// - Parameters: - /// - string: The string representation to decode into a configuration key. - /// - context: Additional configuration context that may influence decoding. - /// - Returns: A structured configuration key representing the decoded string. - func decode(_ string: String, context: [String: ConfigContextValue]) -> ConfigKey -} diff --git a/Sources/Configuration/KeyCoders/ConfigKeyEncoder.swift b/Sources/Configuration/KeyCoders/ConfigKeyEncoder.swift index df8bcf1..3a57f60 100644 --- a/Sources/Configuration/KeyCoders/ConfigKeyEncoder.swift +++ b/Sources/Configuration/KeyCoders/ConfigKeyEncoder.swift @@ -38,8 +38,8 @@ /// /// ## See also /// -/// - ``ConfigKeyDecoder`` - For decoding strings back to keys /// - ``AbsoluteConfigKey`` - The structured key representation +@available(Configuration 1.0, *) public protocol ConfigKeyEncoder: Sendable { /// Encodes a structured configuration key into its string representation. diff --git a/Sources/Configuration/KeyCoders/DotSeparatorKeyDecoder.swift b/Sources/Configuration/KeyCoders/DotSeparatorKeyDecoder.swift new file mode 100644 index 0000000..efee1f8 --- /dev/null +++ b/Sources/Configuration/KeyCoders/DotSeparatorKeyDecoder.swift @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftConfiguration open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftConfiguration project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftConfiguration project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A configuration key decoder that splits string keys using a separator character. +/// +/// This decoder transforms flat string keys into hierarchical ``ConfigKey`` instances +/// by splitting on a specified separator character. It's commonly used with configuration +/// sources that use dot notation. +@available(Configuration 1.0, *) +package struct DotSeparatorKeyDecoder { + /// Decodes a string representation into a structured configuration key. + /// - Parameters: + /// - string: The string representation to decode into a configuration key. + /// - context: Additional configuration context that may influence decoding. + /// - Returns: A structured configuration key representing the decoded string. + package static func decode(_ string: String, context: [String: ConfigContextValue]) -> ConfigKey { + ConfigKey(string.split(separator: ".").map(String.init), context: context) + } +} diff --git a/Sources/Configuration/KeyCoders/SeparatorKeyDecoder.swift b/Sources/Configuration/KeyCoders/SeparatorKeyDecoder.swift deleted file mode 100644 index 0748a94..0000000 --- a/Sources/Configuration/KeyCoders/SeparatorKeyDecoder.swift +++ /dev/null @@ -1,97 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftConfiguration open source project -// -// Copyright (c) 2025 Apple Inc. and the SwiftConfiguration project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftConfiguration project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -/// A configuration key decoder that splits string keys using a separator character. -/// -/// This decoder transforms flat string keys into hierarchical ``ConfigKey`` instances -/// by splitting on a specified separator character. It's commonly used with configuration -/// sources that use dot notation, colon notation, or other delimiter-based key formats. -/// -/// ## Usage -/// -/// Create a decoder with a custom separator: -/// -/// ```swift -/// let decoder = SeparatorKeyDecoder(separator: ".") -/// let key = decoder.decode("database.host.port", context: context) -/// // Results in ConfigKey with components ["database", "host", "port"] -/// ``` -/// -/// Or use one of the predefined separators: -/// -/// ```swift -/// let dotDecoder = ConfigKeyDecoder.dotSeparated -/// let colonDecoder = ConfigKeyDecoder.colonSeparated -/// ``` -@available(Configuration 1.0, *) -public struct SeparatorKeyDecoder: Sendable { - - /// The string used to separate key components. - /// - /// This separator is used to split flat string keys into hierarchical components. - /// Common separators include "." for dot notation and ":" for colon notation. - public var separator: String - - /// Creates a new separator-based key decoder. - /// - /// ```swift - /// let decoder = SeparatorKeyDecoder(separator: "_") - /// let key = decoder.decode("app_config_debug", context: context) - /// // Results in ConfigKey with components ["app", "config", "debug"] - /// ``` - /// - /// - Parameter separator: The string to use for splitting keys into components. - public init(separator: String) { - self.separator = separator - } -} - -@available(Configuration 1.0, *) -extension SeparatorKeyDecoder: ConfigKeyDecoder { - // swift-format-ignore: AllPublicDeclarationsHaveDocumentation - public func decode(_ string: String, context: [String: ConfigContextValue]) -> ConfigKey { - ConfigKey(string.split(separator: separator).map(String.init), context: context) - } -} - -@available(Configuration 1.0, *) -extension ConfigKeyDecoder where Self == SeparatorKeyDecoder { - /// A decoder that uses dot notation for hierarchical keys. - /// - /// This decoder splits keys using "." as the separator, making it suitable for - /// configuration sources that use dot notation like `database.host.port`. - /// - /// ```swift - /// let decoder = ConfigKeyDecoder.dotSeparated - /// let key = decoder.decode("app.database.host", context: context) - /// // Results in ConfigKey with components ["app", "database", "host"] - /// ``` - public static var dotSeparated: Self { - SeparatorKeyDecoder(separator: ".") - } - - /// A decoder that uses colon notation for hierarchical keys. - /// - /// This decoder splits keys using ":" as the separator, making it suitable for - /// configuration sources that use colon notation like `server:port:number`. - /// - /// ```swift - /// let decoder = ConfigKeyDecoder.colonSeparated - /// let key = decoder.decode("app:database:host", context: context) - /// // Results in ConfigKey with components ["app", "database", "host"] - /// ``` - public static var colonSeparated: Self { - SeparatorKeyDecoder(separator: ":") - } -} diff --git a/Sources/Configuration/KeyCoders/SeparatorKeyEncoder.swift b/Sources/Configuration/KeyCoders/SeparatorKeyEncoder.swift index 8a12b4a..d843d0c 100644 --- a/Sources/Configuration/KeyCoders/SeparatorKeyEncoder.swift +++ b/Sources/Configuration/KeyCoders/SeparatorKeyEncoder.swift @@ -36,6 +36,7 @@ /// let dotEncoder = ConfigKeyEncoder.dotSeparated /// let dashEncoder = ConfigKeyEncoder.dashSeparated /// ``` +@available(Configuration 1.0, *) public struct SeparatorKeyEncoder { /// The string used to join key components. @@ -60,6 +61,7 @@ public struct SeparatorKeyEncoder { } } +@available(Configuration 1.0, *) extension SeparatorKeyEncoder: ConfigKeyEncoder { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation public func encode(_ key: AbsoluteConfigKey) -> String { @@ -67,6 +69,7 @@ extension SeparatorKeyEncoder: ConfigKeyEncoder { } } +@available(Configuration 1.0, *) extension ConfigKeyEncoder where Self == SeparatorKeyEncoder { /// An encoder that uses dot notation for hierarchical keys. /// diff --git a/Sources/Configuration/MultiProvider.swift b/Sources/Configuration/MultiProvider.swift index d73dfaf..9aaf936 100644 --- a/Sources/Configuration/MultiProvider.swift +++ b/Sources/Configuration/MultiProvider.swift @@ -209,7 +209,7 @@ extension MultiProvider { updateSequences: &updateSequences, ) { providerUpdateSequences in let updateArrays = combineLatestMany( - elementType: (any ConfigSnapshotProtocol).self, + elementType: (any ConfigSnapshot).self, failureType: Never.self, providerUpdateSequences ) @@ -364,8 +364,8 @@ nonisolated(nonsending) private func withProvidersWatchingValue( @available(Configuration 1.0, *) nonisolated(nonsending) private func withProvidersWatchingSnapshot( providers: ArraySlice, - updateSequences: inout [any (AsyncSequence & Sendable)], - body: ([any (AsyncSequence & Sendable)]) async throws -> ReturnInner + updateSequences: inout [any (AsyncSequence & Sendable)], + body: ([any (AsyncSequence & Sendable)]) async throws -> ReturnInner ) async throws -> ReturnInner { guard let provider = providers.first else { // Recursion termination, once we've collected all update sequences, execute the body. diff --git a/Sources/Configuration/Providers/EnvironmentVariables/EnvironmentKeyEncoder.swift b/Sources/Configuration/Providers/EnvironmentVariables/EnvironmentKeyEncoder.swift index d51aae5..17a9839 100644 --- a/Sources/Configuration/Providers/EnvironmentVariables/EnvironmentKeyEncoder.swift +++ b/Sources/Configuration/Providers/EnvironmentVariables/EnvironmentKeyEncoder.swift @@ -55,10 +55,10 @@ import Foundation /// Only alphanumeric characters (A-Z, a-z, 0-9) are preserved in the final environment /// variable name. All other characters are converted to underscores, ensuring compatibility /// with environment variable naming conventions across different systems. -internal struct EnvironmentKeyEncoder { - -} +@available(Configuration 1.0, *) +internal struct EnvironmentKeyEncoder {} +@available(Configuration 1.0, *) extension EnvironmentKeyEncoder: ConfigKeyEncoder { internal func encode(_ key: AbsoluteConfigKey) -> String { let mappedComponents = key.components.map { component in diff --git a/Sources/Configuration/Providers/InMemory/InMemoryProvider.swift b/Sources/Configuration/Providers/InMemory/InMemoryProvider.swift index 8c7aaee..5228af0 100644 --- a/Sources/Configuration/Providers/InMemory/InMemoryProvider.swift +++ b/Sources/Configuration/Providers/InMemory/InMemoryProvider.swift @@ -107,51 +107,6 @@ public struct InMemoryProvider: Sendable { } } -@available(Configuration 1.0, *) -extension InMemoryProvider { - - /// Creates a new in-memory provider from string keys and configuration values. - /// - /// This convenience initializer allows you to specify configuration keys as strings, - /// which are then decoded into ``AbsoluteConfigKey`` instances using the provided - /// key decoder. This is the most common way to create in-memory providers. - /// - /// ```swift - /// let provider = InMemoryProvider( - /// name: "app-defaults", - /// values: [ - /// "database.host": "localhost", - /// "database.port": 5432, - /// "api.timeout": 30.0, - /// "features.enabled": true, - /// "api.key": ConfigValue("secret", isSecret: true) - /// ] - /// ) - /// ``` - /// - /// - Parameters: - /// - name: An optional name for the provider, used in debugging and logging. - /// - values: A dictionary mapping string keys to configuration values. - /// - keyDecoder: The decoder used to transform string keys into structured keys. - public init( - name: String? = nil, - values: [String: ConfigValue], - keyDecoder: some ConfigKeyDecoder = .dotSeparated - ) { - self.init( - name: name, - values: Dictionary( - uniqueKeysWithValues: values.map { - ( - AbsoluteConfigKey(keyDecoder.decode($0.key, context: [:])), - $0.value - ) - } - ) - ) - } -} - @available(Configuration 1.0, *) extension InMemoryProvider: CustomStringConvertible { // swift-format-ignore: AllPublicDeclarationsHaveDocumentation diff --git a/Sources/Configuration/Providers/InMemory/MutableInMemoryProvider.swift b/Sources/Configuration/Providers/InMemory/MutableInMemoryProvider.swift index 2335659..838db44 100644 --- a/Sources/Configuration/Providers/InMemory/MutableInMemoryProvider.swift +++ b/Sources/Configuration/Providers/InMemory/MutableInMemoryProvider.swift @@ -147,48 +147,6 @@ public final class MutableInMemoryProvider: Sendable { @available(Configuration 1.0, *) extension MutableInMemoryProvider { - /// Creates a new mutable in-memory provider from string keys and initial values. - /// - /// This convenience initializer allows you to specify configuration keys as strings, - /// which are then decoded into ``AbsoluteConfigKey`` instances using the provided - /// key decoder. This is the most common way to create mutable in-memory providers. - /// - /// ```swift - /// let provider = MutableInMemoryProvider( - /// name: "feature-flags", - /// initialValues: [ - /// "features.new-ui": false, - /// "features.beta-api": true, - /// "limits.max-requests": 1000 - /// ] - /// ) - /// - /// // Toggle features at runtime - /// provider.setValue(true, forKey: "features.new-ui") - /// ``` - /// - /// - Parameters: - /// - name: An optional name for the provider, used in debugging and logging. - /// - initialValues: A dictionary mapping string keys to initial configuration values. - /// - keyDecoder: The decoder used to transform string keys into structured keys. - public convenience init( - name: String? = nil, - initialValues: [String: ConfigValue], - keyDecoder: some ConfigKeyDecoder = .dotSeparated - ) { - self.init( - name: name, - initialValues: Dictionary( - uniqueKeysWithValues: initialValues.map { - ( - AbsoluteConfigKey(keyDecoder.decode($0.key, context: [:])), - $0.value - ) - } - ) - ) - } - /// Updates the stored value for the specified configuration key. /// /// This method atomically updates the value and notifies all active watchers @@ -235,41 +193,6 @@ extension MutableInMemoryProvider { } } } - - /// Updates the stored value for the specified string key. - /// - /// This convenience method allows you to update values using string keys, - /// which are decoded into ``AbsoluteConfigKey`` instances using the provided - /// key decoder and context. - /// - /// ```swift - /// let provider = MutableInMemoryProvider(initialValues: [:]) - /// - /// // Set values using string keys - /// provider.setValue("localhost", forKey: "database.host") - /// provider.setValue(5432, forKey: "database.port") - /// - /// // Use context for environment-specific keys - /// provider.setValue( - /// "prod-db", - /// forKey: "database.host", - /// context: ["env": "production"] - /// ) - /// ``` - /// - /// - Parameters: - /// - value: The new configuration value, or `nil` to remove the value entirely. - /// - key: The string representation of the configuration key. - /// - context: Additional context information for key resolution. - /// - keyDecoder: The decoder used to transform the string key into a structured key. - public func setValue( - _ value: ConfigValue?, - forKey key: String, - context: [String: ConfigContextValue] = [:], - keyDecoder: some ConfigKeyDecoder = .dotSeparated - ) { - setValue(value, forKey: AbsoluteConfigKey(keyDecoder.decode(key, context: context))) - } } @available(Configuration 1.0, *) diff --git a/Sources/Configuration/Providers/Wrappers/ConfigProvider+Operators.swift b/Sources/Configuration/Providers/Wrappers/ConfigProvider+Operators.swift index 3bd028b..73c387e 100644 --- a/Sources/Configuration/Providers/Wrappers/ConfigProvider+Operators.swift +++ b/Sources/Configuration/Providers/Wrappers/ConfigProvider+Operators.swift @@ -24,24 +24,6 @@ extension ConfigProvider { } } - /// Creates a new prefixed configuration provider with a string prefix. - /// - /// This convenience method allows you to specify a string prefix that will be - /// decoded using the provided key decoder. - /// - /// - Parameters: - /// - prefix: The string prefix to decode and prepend to all configuration keys. - /// - context: Additional context used when decoding the prefix string. - /// - keyDecoder: The decoder to use for parsing the prefix string. - /// - Returns: A provider which prefixes keys. - public func prefixKeys( - with prefix: String, - context: [String: ConfigContextValue] = [:], - keyDecoder: some ConfigKeyDecoder = .dotSeparated - ) -> KeyMappingProvider { - self.prefixKeys(with: keyDecoder.decode(prefix, context: context)) - } - /// Creates a new configuration provider where each key is rewritten by the given closure. /// /// - Parameter transform: The closure applied to each key before a lookup. diff --git a/Sources/ConfigurationTesting/ProviderCompatTest.swift b/Sources/ConfigurationTesting/ProviderCompatTest.swift index 0a9f1e9..ea19af8 100644 --- a/Sources/ConfigurationTesting/ProviderCompatTest.swift +++ b/Sources/ConfigurationTesting/ProviderCompatTest.swift @@ -113,7 +113,7 @@ public struct ProviderCompatTest: Sendable { try await watchSnapshot() } - let keyDecoder = SeparatorKeyDecoder.dotSeparated + let keyDecoder = DotSeparatorKeyDecoder.self let expectedValues: [(String, ConfigType, ConfigContent?)] = [ ("string", .string, .string("Hello")), ("absent.string", .string, nil), diff --git a/Sources/ConfigurationTestingInternal/TestProvider.swift b/Sources/ConfigurationTestingInternal/TestProvider.swift index 0f70c6a..dbce159 100644 --- a/Sources/ConfigurationTestingInternal/TestProvider.swift +++ b/Sources/ConfigurationTestingInternal/TestProvider.swift @@ -54,34 +54,6 @@ package struct TestProvider: Sendable { } } -@available(Configuration 1.0, *) -extension TestProvider { - - /// Creates a new test provider with string-based key mappings. - /// - /// This convenience initializer allows you to specify keys as strings rather - /// than ``AbsoluteConfigKey`` instances. - /// - /// - Parameters: - /// - name: An optional name for the provider (currently unused). - /// - values: A dictionary mapping string keys to their expected results. - /// - keyDecoder: The decoder to use for converting string keys to ``AbsoluteConfigKey``. - package init( - name: String? = nil, - values: [String: Result], - keyDecoder: some ConfigKeyDecoder = .dotSeparated - ) { - self.values = Dictionary( - uniqueKeysWithValues: values.map { - ( - AbsoluteConfigKey(keyDecoder.decode($0.key, context: [:])), - $0.value - ) - } - ) - } -} - @available(Configuration 1.0, *) extension TestProvider: ConfigProvider, ConfigSnapshot { package var providerName: String { diff --git a/Tests/ConfigurationTests/AbsoluteConfigKeyTests.swift b/Tests/ConfigurationTests/AbsoluteConfigKeyTests.swift index 0ade572..af40e1c 100644 --- a/Tests/ConfigurationTests/AbsoluteConfigKeyTests.swift +++ b/Tests/ConfigurationTests/AbsoluteConfigKeyTests.swift @@ -16,6 +16,7 @@ import Testing @testable import Configuration struct AbsoluteConfigKeyTests { + @available(Configuration 1.0, *) @Test func prependingSimpleKey() { let base = AbsoluteConfigKey(["bar", "baz"]) let prefix = ConfigKey(["foo"]) @@ -25,6 +26,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context.isEmpty) } + @available(Configuration 1.0, *) @Test func prependingWithContext() { let base = AbsoluteConfigKey(["bar"], context: ["env": .string("prod")]) let prefix = ConfigKey(["foo"], context: ["region": .string("us-west")]) @@ -35,6 +37,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context["region"] == .string("us-west")) } + @available(Configuration 1.0, *) @Test func prependingWithConflictingContext() { let base = AbsoluteConfigKey(["bar"], context: ["key": .string("base-value")]) let prefix = ConfigKey(["foo"], context: ["key": .string("prefix-value")]) @@ -44,6 +47,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context["key"] == .string("base-value")) } + @available(Configuration 1.0, *) @Test func prependingEmptyKey() { let base = AbsoluteConfigKey(["foo", "bar"]) let prefix = ConfigKey([]) @@ -53,6 +57,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context.isEmpty) } + @available(Configuration 1.0, *) @Test func appendingSimpleKey() { let base = AbsoluteConfigKey(["foo", "bar"]) let suffix = ConfigKey(["baz"]) @@ -62,6 +67,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context.isEmpty) } + @available(Configuration 1.0, *) @Test func appendingWithContext() { let base = AbsoluteConfigKey(["foo"], context: ["env": .string("prod")]) let suffix = ConfigKey(["bar"], context: ["region": .string("us-west")]) @@ -72,6 +78,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context["region"] == .string("us-west")) } + @available(Configuration 1.0, *) @Test func appendingWithConflictingContext() { let base = AbsoluteConfigKey(["foo"], context: ["key": .string("base-value")]) let suffix = ConfigKey(["bar"], context: ["key": .string("suffix-value")]) @@ -81,6 +88,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context["key"] == .string("suffix-value")) } + @available(Configuration 1.0, *) @Test func appendingEmptyKey() { let base = AbsoluteConfigKey(["foo", "bar"]) let suffix = ConfigKey([]) @@ -90,6 +98,7 @@ struct AbsoluteConfigKeyTests { #expect(result.context.isEmpty) } + @available(Configuration 1.0, *) @Test func appendingMultipleKeys() { let base = AbsoluteConfigKey(["foo"]) let result = base.appending(ConfigKey(["bar"])).appending(ConfigKey(["baz"])) @@ -97,6 +106,7 @@ struct AbsoluteConfigKeyTests { #expect(result.components == ["foo", "bar", "baz"]) } + @available(Configuration 1.0, *) @Test func prependingMultipleKeys() { let base = AbsoluteConfigKey(["baz"]) let result = base.prepending(ConfigKey(["bar"])).prepending(ConfigKey(["foo"])) @@ -104,6 +114,7 @@ struct AbsoluteConfigKeyTests { #expect(result.components == ["foo", "bar", "baz"]) } + @available(Configuration 1.0, *) @Test func prependingAndAppending() { let base = AbsoluteConfigKey(["middle"]) let result = base.prepending(ConfigKey(["start"])).appending(ConfigKey(["end"])) diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift index ba6a19c..0f81c9e 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift @@ -34,610 +34,365 @@ struct ConfigReaderMethodTestsFetch1 { do { // Optional - success - #expect(try await config.fetchString(forKey: ConfigKey(["string"])) == Defaults.string) #expect(try await config.fetchString(forKey: "string") == Defaults.string) // Optional - missing - #expect(try await config.fetchString(forKey: ConfigKey(["absentString"])) == nil) #expect(try await config.fetchString(forKey: "absentString") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchString(forKey: ConfigKey(["string"]), default: Defaults.otherString) - == Defaults.string - ) #expect(try await config.fetchString(forKey: "string", default: Defaults.otherString) == Defaults.string) // Defaulted - missing - #expect( - try await config.fetchString(forKey: ConfigKey(["absentString"]), default: Defaults.otherString) - == Defaults.otherString - ) #expect( try await config.fetchString(forKey: "absentString", default: Defaults.otherString) == Defaults.otherString ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString(forKey: ConfigKey(["failure"]), default: Defaults.otherString) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString(forKey: "failure", default: Defaults.otherString) } // Required - success - #expect(try await config.fetchRequiredString(forKey: ConfigKey(["string"])) == Defaults.string) #expect(try await config.fetchRequiredString(forKey: "string") == Defaults.string) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredString(forKey: ConfigKey(["absentString"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredString(forKey: "absentString") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredString(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredString(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchInt(forKey: ConfigKey(["int"])) == Defaults.int) #expect(try await config.fetchInt(forKey: "int") == Defaults.int) // Optional - missing - #expect(try await config.fetchInt(forKey: ConfigKey(["absentInt"])) == nil) #expect(try await config.fetchInt(forKey: "absentInt") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchInt(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchInt(forKey: "failure") } // Defaulted - success - #expect(try await config.fetchInt(forKey: ConfigKey(["int"]), default: Defaults.otherInt) == Defaults.int) #expect(try await config.fetchInt(forKey: "int", default: Defaults.otherInt) == Defaults.int) // Defaulted - missing - #expect( - try await config.fetchInt(forKey: ConfigKey(["absentInt"]), default: Defaults.otherInt) - == Defaults.otherInt - ) #expect(try await config.fetchInt(forKey: "absentInt", default: Defaults.otherInt) == Defaults.otherInt) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchInt(forKey: ConfigKey(["failure"]), default: Defaults.otherInt) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchInt(forKey: "failure", default: Defaults.otherInt) } // Required - success - #expect(try await config.fetchRequiredInt(forKey: ConfigKey(["int"])) == Defaults.int) #expect(try await config.fetchRequiredInt(forKey: "int") == Defaults.int) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredInt(forKey: ConfigKey(["absentInt"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredInt(forKey: "absentInt") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredInt(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredInt(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchDouble(forKey: ConfigKey(["double"])) == Defaults.double) #expect(try await config.fetchDouble(forKey: "double") == Defaults.double) // Optional - missing - #expect(try await config.fetchDouble(forKey: ConfigKey(["absentDouble"])) == nil) #expect(try await config.fetchDouble(forKey: "absentDouble") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchDouble(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchDouble(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchDouble(forKey: ConfigKey(["double"]), default: Defaults.otherDouble) - == Defaults.double - ) #expect(try await config.fetchDouble(forKey: "double", default: Defaults.otherDouble) == Defaults.double) // Defaulted - missing - #expect( - try await config.fetchDouble(forKey: ConfigKey(["absentDouble"]), default: Defaults.otherDouble) - == Defaults.otherDouble - ) #expect( try await config.fetchDouble(forKey: "absentDouble", default: Defaults.otherDouble) == Defaults.otherDouble ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchDouble(forKey: ConfigKey(["failure"]), default: Defaults.otherDouble) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchDouble(forKey: "failure", default: Defaults.otherDouble) } // Required - success - #expect(try await config.fetchRequiredDouble(forKey: ConfigKey(["double"])) == Defaults.double) #expect(try await config.fetchRequiredDouble(forKey: "double") == Defaults.double) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredDouble(forKey: ConfigKey(["absentDouble"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredDouble(forKey: "absentDouble") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredDouble(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredDouble(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchBool(forKey: ConfigKey(["bool"])) == Defaults.bool) #expect(try await config.fetchBool(forKey: "bool") == Defaults.bool) // Optional - missing - #expect(try await config.fetchBool(forKey: ConfigKey(["absentBool"])) == nil) #expect(try await config.fetchBool(forKey: "absentBool") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBool(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBool(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchBool(forKey: ConfigKey(["bool"]), default: Defaults.otherBool) == Defaults.bool - ) #expect(try await config.fetchBool(forKey: "bool", default: Defaults.otherBool) == Defaults.bool) // Defaulted - missing - #expect( - try await config.fetchBool(forKey: ConfigKey(["absentBool"]), default: Defaults.otherBool) - == Defaults.otherBool - ) #expect(try await config.fetchBool(forKey: "absentBool", default: Defaults.otherBool) == Defaults.otherBool) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBool(forKey: ConfigKey(["failure"]), default: Defaults.otherBool) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBool(forKey: "failure", default: Defaults.otherBool) } // Required - success - #expect(try await config.fetchRequiredBool(forKey: ConfigKey(["bool"])) == Defaults.bool) #expect(try await config.fetchRequiredBool(forKey: "bool") == Defaults.bool) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredBool(forKey: ConfigKey(["absentBool"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredBool(forKey: "absentBool") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredBool(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredBool(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchBytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) #expect(try await config.fetchBytes(forKey: "bytes") == Defaults.bytes) // Optional - missing - #expect(try await config.fetchBytes(forKey: ConfigKey(["absentBytes"])) == nil) #expect(try await config.fetchBytes(forKey: "absentBytes") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBytes(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBytes(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchBytes(forKey: ConfigKey(["bytes"]), default: Defaults.otherBytes) - == Defaults.bytes - ) #expect(try await config.fetchBytes(forKey: "bytes", default: Defaults.otherBytes) == Defaults.bytes) // Defaulted - missing - #expect( - try await config.fetchBytes(forKey: ConfigKey(["absentBytes"]), default: Defaults.otherBytes) - == Defaults.otherBytes - ) #expect( try await config.fetchBytes(forKey: "absentBytes", default: Defaults.otherBytes) == Defaults.otherBytes ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBytes(forKey: ConfigKey(["failure"]), default: Defaults.otherBytes) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBytes(forKey: "failure", default: Defaults.otherBytes) } // Required - success - #expect(try await config.fetchRequiredBytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) #expect(try await config.fetchRequiredBytes(forKey: "bytes") == Defaults.bytes) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredBytes(forKey: ConfigKey(["absentBytes"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredBytes(forKey: "absentBytes") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredBytes(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredBytes(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchStringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray) #expect(try await config.fetchStringArray(forKey: "stringArray") == Defaults.stringArray) // Optional - missing - #expect(try await config.fetchStringArray(forKey: ConfigKey(["absentStringArray"])) == nil) #expect(try await config.fetchStringArray(forKey: "absentStringArray") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["stringArray"]), - default: Defaults.otherStringArray - ) == Defaults.stringArray - ) #expect( try await config.fetchStringArray(forKey: "stringArray", default: Defaults.otherStringArray) == Defaults.stringArray ) // Defaulted - missing - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["absentStringArray"]), - default: Defaults.otherStringArray - ) == Defaults.otherStringArray - ) #expect( try await config.fetchStringArray(forKey: "absentStringArray", default: Defaults.otherStringArray) == Defaults.otherStringArray ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray(forKey: ConfigKey(["failure"]), default: Defaults.otherStringArray) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray(forKey: "failure", default: Defaults.otherStringArray) } // Required - success - #expect( - try await config.fetchRequiredStringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray - ) #expect(try await config.fetchRequiredStringArray(forKey: "stringArray") == Defaults.stringArray) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredStringArray(forKey: ConfigKey(["absentStringArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredStringArray(forKey: "absentStringArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredStringArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredStringArray(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchIntArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) #expect(try await config.fetchIntArray(forKey: "intArray") == Defaults.intArray) // Optional - missing - #expect(try await config.fetchIntArray(forKey: ConfigKey(["absentIntArray"])) == nil) #expect(try await config.fetchIntArray(forKey: "absentIntArray") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchIntArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchIntArray(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchIntArray(forKey: ConfigKey(["intArray"]), default: Defaults.otherIntArray) - == Defaults.intArray - ) #expect( try await config.fetchIntArray(forKey: "intArray", default: Defaults.otherIntArray) == Defaults.intArray ) // Defaulted - missing - #expect( - try await config.fetchIntArray(forKey: ConfigKey(["absentIntArray"]), default: Defaults.otherIntArray) - == Defaults.otherIntArray - ) #expect( try await config.fetchIntArray(forKey: "absentIntArray", default: Defaults.otherIntArray) == Defaults.otherIntArray ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchIntArray(forKey: ConfigKey(["failure"]), default: Defaults.otherIntArray) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchIntArray(forKey: "failure", default: Defaults.otherIntArray) } // Required - success - #expect(try await config.fetchRequiredIntArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) #expect(try await config.fetchRequiredIntArray(forKey: "intArray") == Defaults.intArray) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredIntArray(forKey: ConfigKey(["absentIntArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredIntArray(forKey: "absentIntArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredIntArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredIntArray(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchDoubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray) #expect(try await config.fetchDoubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Optional - missing - #expect(try await config.fetchDoubleArray(forKey: ConfigKey(["absentDoubleArray"])) == nil) #expect(try await config.fetchDoubleArray(forKey: "absentDoubleArray") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchDoubleArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchDoubleArray(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchDoubleArray( - forKey: ConfigKey(["doubleArray"]), - default: Defaults.otherDoubleArray - ) == Defaults.doubleArray - ) #expect( try await config.fetchDoubleArray(forKey: "doubleArray", default: Defaults.otherDoubleArray) == Defaults.doubleArray ) // Defaulted - missing - #expect( - try await config.fetchDoubleArray( - forKey: ConfigKey(["absentDoubleArray"]), - default: Defaults.otherDoubleArray - ) == Defaults.otherDoubleArray - ) #expect( try await config.fetchDoubleArray(forKey: "absentDoubleArray", default: Defaults.otherDoubleArray) == Defaults.otherDoubleArray ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchDoubleArray(forKey: ConfigKey(["failure"]), default: Defaults.otherDoubleArray) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchDoubleArray(forKey: "failure", default: Defaults.otherDoubleArray) } // Required - success - #expect( - try await config.fetchRequiredDoubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray - ) #expect(try await config.fetchRequiredDoubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredDoubleArray(forKey: ConfigKey(["absentDoubleArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredDoubleArray(forKey: "absentDoubleArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredDoubleArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredDoubleArray(forKey: "failure") } } do { // Optional - success - #expect(try await config.fetchBoolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) #expect(try await config.fetchBoolArray(forKey: "boolArray") == Defaults.boolArray) // Optional - missing - #expect(try await config.fetchBoolArray(forKey: ConfigKey(["absentBoolArray"])) == nil) #expect(try await config.fetchBoolArray(forKey: "absentBoolArray") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBoolArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBoolArray(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchBoolArray(forKey: ConfigKey(["boolArray"]), default: Defaults.otherBoolArray) - == Defaults.boolArray - ) #expect( try await config.fetchBoolArray(forKey: "boolArray", default: Defaults.otherBoolArray) == Defaults.boolArray ) // Defaulted - missing - #expect( - try await config.fetchBoolArray( - forKey: ConfigKey(["absentBoolArray"]), - default: Defaults.otherBoolArray - ) == Defaults.otherBoolArray - ) #expect( try await config.fetchBoolArray(forKey: "absentBoolArray", default: Defaults.otherBoolArray) == Defaults.otherBoolArray ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchBoolArray(forKey: ConfigKey(["failure"]), default: Defaults.otherBoolArray) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchBoolArray(forKey: "failure", default: Defaults.otherBoolArray) } // Required - success - #expect(try await config.fetchRequiredBoolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) #expect(try await config.fetchRequiredBoolArray(forKey: "boolArray") == Defaults.boolArray) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredBoolArray(forKey: ConfigKey(["absentBoolArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredBoolArray(forKey: "absentBoolArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredBoolArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredBoolArray(forKey: "failure") } } do { // Optional - success - #expect( - try await config.fetchByteChunkArray(forKey: ConfigKey(["byteChunkArray"])) == Defaults.byteChunkArray - ) #expect(try await config.fetchByteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Optional - missing - #expect(try await config.fetchByteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) == nil) #expect(try await config.fetchByteChunkArray(forKey: "absentByteChunkArray") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchByteChunkArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchByteChunkArray(forKey: "failure") } // Defaulted - success - #expect( - try await config.fetchByteChunkArray( - forKey: ConfigKey(["byteChunkArray"]), - default: Defaults.otherByteChunkArray - ) == Defaults.byteChunkArray - ) #expect( try await config.fetchByteChunkArray(forKey: "byteChunkArray", default: Defaults.otherByteChunkArray) == Defaults.byteChunkArray ) // Defaulted - missing - #expect( - try await config.fetchByteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - default: Defaults.otherByteChunkArray - ) == Defaults.otherByteChunkArray - ) #expect( try await config.fetchByteChunkArray( forKey: "absentByteChunkArray", @@ -646,37 +401,20 @@ struct ConfigReaderMethodTestsFetch1 { ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchByteChunkArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherByteChunkArray - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchByteChunkArray(forKey: "failure", default: Defaults.otherByteChunkArray) } // Required - success - #expect( - try await config.fetchRequiredByteChunkArray(forKey: ConfigKey(["byteChunkArray"])) - == Defaults.byteChunkArray - ) #expect(try await config.fetchRequiredByteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredByteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredByteChunkArray(forKey: "absentByteChunkArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredByteChunkArray(forKey: ConfigKey(["failure"])) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredByteChunkArray(forKey: "failure") } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift.gyb index 2a94889..4904b84 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch1.swift.gyb @@ -35,41 +35,31 @@ struct ConfigReaderMethodTestsFetch1 { % lower_name = lower_first(name) do { // Optional - success - #expect(try await config.fetch${name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) #expect(try await config.fetch${name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Optional - missing - #expect(try await config.fetch${name}(forKey: ConfigKey(["absent${name}"])) == nil) #expect(try await config.fetch${name}(forKey: "absent${name}") == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${name}(forKey: ConfigKey(["failure"])) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${name}(forKey: "failure") } // Defaulted - success - #expect(try await config.fetch${name}(forKey: ConfigKey(["${lower_name}"]), default: Defaults.other${name}) == Defaults.${lower_name}) #expect(try await config.fetch${name}(forKey: "${lower_name}", default: Defaults.other${name}) == Defaults.${lower_name}) // Defaulted - missing - #expect(try await config.fetch${name}(forKey: ConfigKey(["absent${name}"]), default: Defaults.other${name}) == Defaults.other${name}) #expect(try await config.fetch${name}(forKey: "absent${name}", default: Defaults.other${name}) == Defaults.other${name}) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${name}(forKey: ConfigKey(["failure"]), default: Defaults.other${name}) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${name}(forKey: "failure", default: Defaults.other${name}) } // Required - success - #expect(try await config.fetchRequired${name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) #expect(try await config.fetchRequired${name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${name}(forKey: ConfigKey(["absent${name}"])) } + let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${name}(forKey: "absent${name}") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${name}(forKey: "absent${name}") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${name}(forKey: ConfigKey(["failure"])) } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${name}(forKey: "failure") } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift index 771eed2..3b0ff13 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift @@ -34,42 +34,22 @@ struct ConfigReaderMethodTestsFetch2 { do { // Optional - success - #expect( - try await config.fetchString(forKey: ConfigKey(["stringConvertible"]), as: TestStringConvertible.self) - == Defaults.stringConvertible - ) #expect( try await config.fetchString(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible ) // Optional - missing - #expect( - try await config.fetchString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self - ) == nil - ) #expect( try await config.fetchString(forKey: "absentStringConvertible", as: TestStringConvertible.self) == nil ) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString(forKey: "failure", as: TestStringConvertible.self) } // Defaulted - success - #expect( - try await config.fetchString( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.stringConvertible - ) #expect( try await config.fetchString( forKey: "stringConvertible", @@ -79,13 +59,6 @@ struct ConfigReaderMethodTestsFetch2 { ) // Defaulted - missing - #expect( - try await config.fetchString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.otherStringConvertible - ) #expect( try await config.fetchString( forKey: "absentStringConvertible", @@ -95,13 +68,6 @@ struct ConfigReaderMethodTestsFetch2 { ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString( forKey: "failure", @@ -111,12 +77,6 @@ struct ConfigReaderMethodTestsFetch2 { } // Required - success - #expect( - try await config.fetchRequiredString( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self - ) == Defaults.stringConvertible - ) #expect( try await config.fetchRequiredString(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible @@ -124,66 +84,34 @@ struct ConfigReaderMethodTestsFetch2 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredString(forKey: "absentStringConvertible", as: TestStringConvertible.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredString(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredString(forKey: "failure", as: TestStringConvertible.self) } } do { // Optional - success - #expect( - try await config.fetchString(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) - == Defaults.stringEnum - ) #expect(try await config.fetchString(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum) // Optional - missing - #expect(try await config.fetchString(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) == nil) #expect(try await config.fetchString(forKey: "absentStringEnum", as: TestEnum.self) == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString(forKey: "failure", as: TestEnum.self) } // Defaulted - success - #expect( - try await config.fetchString( - forKey: ConfigKey(["stringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum - ) == Defaults.stringEnum - ) #expect( try await config.fetchString(forKey: "stringEnum", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.stringEnum ) // Defaulted - missing - #expect( - try await config.fetchString( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum - ) == Defaults.otherStringEnum - ) #expect( try await config.fetchString( forKey: "absentStringEnum", @@ -193,40 +121,22 @@ struct ConfigReaderMethodTestsFetch2 { ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchString( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnum - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchString(forKey: "failure", as: TestEnum.self, default: Defaults.otherStringEnum) } // Required - success - #expect( - try await config.fetchRequiredString(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) - == Defaults.stringEnum - ) #expect( try await config.fetchRequiredString(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum ) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredString(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredString(forKey: "absentStringEnum", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredString(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredString(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift.gyb index 2fd0b07..c76e302 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch2.swift.gyb @@ -37,41 +37,31 @@ struct ConfigReaderMethodTestsFetch2 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try await config.fetch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(try await config.fetch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: "failure", as: ${test_type}.self) } // Defaulted - success - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(try await config.fetch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(try await config.fetch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) } // Required - success - #expect(try await config.fetchRequired${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try await config.fetchRequired${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${suffix}(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift index e87014f..4517370 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift @@ -34,24 +34,12 @@ struct ConfigReaderMethodTestsFetch3 { do { // Optional - success - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self - ) == Defaults.stringConvertibleArray - ) #expect( try await config.fetchStringArray(forKey: "stringConvertibleArray", as: TestStringConvertible.self) == Defaults.stringConvertibleArray ) // Optional - missing - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self - ) == nil - ) #expect( try await config.fetchStringArray( forKey: "absentStringConvertibleArray", @@ -60,21 +48,11 @@ struct ConfigReaderMethodTestsFetch3 { ) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray(forKey: "failure", as: TestStringConvertible.self) } // Defaulted - success - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.stringConvertibleArray - ) #expect( try await config.fetchStringArray( forKey: "stringConvertibleArray", @@ -84,13 +62,6 @@ struct ConfigReaderMethodTestsFetch3 { ) // Defaulted - missing - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.otherStringConvertibleArray - ) #expect( try await config.fetchStringArray( forKey: "absentStringConvertibleArray", @@ -100,13 +71,6 @@ struct ConfigReaderMethodTestsFetch3 { ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray( forKey: "failure", @@ -116,12 +80,6 @@ struct ConfigReaderMethodTestsFetch3 { } // Required - success - #expect( - try await config.fetchRequiredStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self - ) == Defaults.stringConvertibleArray - ) #expect( try await config.fetchRequiredStringArray( forKey: "stringConvertibleArray", @@ -131,65 +89,34 @@ struct ConfigReaderMethodTestsFetch3 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredStringArray( forKey: "absentStringConvertibleArray", as: TestStringConvertible.self ) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredStringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredStringArray(forKey: "failure", as: TestStringConvertible.self) } } do { // Optional - success - #expect( - try await config.fetchStringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) #expect( try await config.fetchStringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray ) // Optional - missing - #expect( - try await config.fetchStringArray(forKey: ConfigKey(["absentStringEnumArray"]), as: TestEnum.self) - == nil - ) #expect(try await config.fetchStringArray(forKey: "absentStringEnumArray", as: TestEnum.self) == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray(forKey: "failure", as: TestEnum.self) } // Defaulted - success - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.stringEnumArray - ) #expect( try await config.fetchStringArray( forKey: "stringEnumArray", @@ -199,13 +126,6 @@ struct ConfigReaderMethodTestsFetch3 { ) // Defaulted - missing - #expect( - try await config.fetchStringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.otherStringEnumArray - ) #expect( try await config.fetchStringArray( forKey: "absentStringEnumArray", @@ -215,13 +135,6 @@ struct ConfigReaderMethodTestsFetch3 { ) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchStringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchStringArray( forKey: "failure", @@ -231,10 +144,6 @@ struct ConfigReaderMethodTestsFetch3 { } // Required - success - #expect( - try await config.fetchRequiredStringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) #expect( try await config.fetchRequiredStringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray @@ -242,21 +151,11 @@ struct ConfigReaderMethodTestsFetch3 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.fetchRequiredStringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequiredStringArray(forKey: "absentStringEnumArray", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.fetchRequiredStringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequiredStringArray(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift.gyb index 0223ad6..77e4c00 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsFetch3.swift.gyb @@ -37,41 +37,31 @@ struct ConfigReaderMethodTestsFetch3 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try await config.fetch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(try await config.fetch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: "failure", as: ${test_type}.self) } // Defaulted - success - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(try await config.fetch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(try await config.fetch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(try await config.fetch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) } await #expect(throws: TestProvider.TestError.self) { try await config.fetch${suffix}(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) } // Required - success - #expect(try await config.fetchRequired${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try await config.fetchRequired${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.fetchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } await #expect(throws: TestProvider.TestError.self) { try await config.fetchRequired${suffix}(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift index eb7bdbb..d03cd16 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift @@ -34,509 +34,325 @@ struct ConfigReaderMethodTestsGet1 { do { // Optional - success - #expect(config.string(forKey: ConfigKey(["string"])) == Defaults.string) #expect(config.string(forKey: "string") == Defaults.string) // Optional - missing - #expect(config.string(forKey: ConfigKey(["absentString"])) == nil) #expect(config.string(forKey: "absentString") == nil) // Optional - failing - #expect(config.string(forKey: ConfigKey(["failure"])) == nil) #expect(config.string(forKey: "failure") == nil) // Defaulted - success - #expect(config.string(forKey: ConfigKey(["string"]), default: Defaults.otherString) == Defaults.string) #expect(config.string(forKey: "string", default: Defaults.otherString) == Defaults.string) // Defaulted - missing - #expect( - config.string(forKey: ConfigKey(["absentString"]), default: Defaults.otherString) - == Defaults.otherString - ) #expect(config.string(forKey: "absentString", default: Defaults.otherString) == Defaults.otherString) // Defaulted - failing - #expect( - config.string(forKey: ConfigKey(["failure"]), default: Defaults.otherString) == Defaults.otherString - ) #expect(config.string(forKey: "failure", default: Defaults.otherString) == Defaults.otherString) // Required - success - #expect(try config.requiredString(forKey: ConfigKey(["string"])) == Defaults.string) #expect(try config.requiredString(forKey: "string") == Defaults.string) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredString(forKey: ConfigKey(["absentString"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absentString") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absentString") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: "failure") } } do { // Optional - success - #expect(config.int(forKey: ConfigKey(["int"])) == Defaults.int) #expect(config.int(forKey: "int") == Defaults.int) // Optional - missing - #expect(config.int(forKey: ConfigKey(["absentInt"])) == nil) #expect(config.int(forKey: "absentInt") == nil) // Optional - failing - #expect(config.int(forKey: ConfigKey(["failure"])) == nil) #expect(config.int(forKey: "failure") == nil) // Defaulted - success - #expect(config.int(forKey: ConfigKey(["int"]), default: Defaults.otherInt) == Defaults.int) #expect(config.int(forKey: "int", default: Defaults.otherInt) == Defaults.int) // Defaulted - missing - #expect(config.int(forKey: ConfigKey(["absentInt"]), default: Defaults.otherInt) == Defaults.otherInt) #expect(config.int(forKey: "absentInt", default: Defaults.otherInt) == Defaults.otherInt) // Defaulted - failing - #expect(config.int(forKey: ConfigKey(["failure"]), default: Defaults.otherInt) == Defaults.otherInt) #expect(config.int(forKey: "failure", default: Defaults.otherInt) == Defaults.otherInt) // Required - success - #expect(try config.requiredInt(forKey: ConfigKey(["int"])) == Defaults.int) #expect(try config.requiredInt(forKey: "int") == Defaults.int) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try config.requiredInt(forKey: ConfigKey(["absentInt"])) } + let error1 = #expect(throws: ConfigError.self) { try config.requiredInt(forKey: "absentInt") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredInt(forKey: "absentInt") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredInt(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredInt(forKey: "failure") } } do { // Optional - success - #expect(config.double(forKey: ConfigKey(["double"])) == Defaults.double) #expect(config.double(forKey: "double") == Defaults.double) // Optional - missing - #expect(config.double(forKey: ConfigKey(["absentDouble"])) == nil) #expect(config.double(forKey: "absentDouble") == nil) // Optional - failing - #expect(config.double(forKey: ConfigKey(["failure"])) == nil) #expect(config.double(forKey: "failure") == nil) // Defaulted - success - #expect(config.double(forKey: ConfigKey(["double"]), default: Defaults.otherDouble) == Defaults.double) #expect(config.double(forKey: "double", default: Defaults.otherDouble) == Defaults.double) // Defaulted - missing - #expect( - config.double(forKey: ConfigKey(["absentDouble"]), default: Defaults.otherDouble) - == Defaults.otherDouble - ) #expect(config.double(forKey: "absentDouble", default: Defaults.otherDouble) == Defaults.otherDouble) // Defaulted - failing - #expect( - config.double(forKey: ConfigKey(["failure"]), default: Defaults.otherDouble) == Defaults.otherDouble - ) #expect(config.double(forKey: "failure", default: Defaults.otherDouble) == Defaults.otherDouble) // Required - success - #expect(try config.requiredDouble(forKey: ConfigKey(["double"])) == Defaults.double) #expect(try config.requiredDouble(forKey: "double") == Defaults.double) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredDouble(forKey: ConfigKey(["absentDouble"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredDouble(forKey: "absentDouble") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredDouble(forKey: "absentDouble") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredDouble(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredDouble(forKey: "failure") } } do { // Optional - success - #expect(config.bool(forKey: ConfigKey(["bool"])) == Defaults.bool) #expect(config.bool(forKey: "bool") == Defaults.bool) // Optional - missing - #expect(config.bool(forKey: ConfigKey(["absentBool"])) == nil) #expect(config.bool(forKey: "absentBool") == nil) // Optional - failing - #expect(config.bool(forKey: ConfigKey(["failure"])) == nil) #expect(config.bool(forKey: "failure") == nil) // Defaulted - success - #expect(config.bool(forKey: ConfigKey(["bool"]), default: Defaults.otherBool) == Defaults.bool) #expect(config.bool(forKey: "bool", default: Defaults.otherBool) == Defaults.bool) // Defaulted - missing - #expect(config.bool(forKey: ConfigKey(["absentBool"]), default: Defaults.otherBool) == Defaults.otherBool) #expect(config.bool(forKey: "absentBool", default: Defaults.otherBool) == Defaults.otherBool) // Defaulted - failing - #expect(config.bool(forKey: ConfigKey(["failure"]), default: Defaults.otherBool) == Defaults.otherBool) #expect(config.bool(forKey: "failure", default: Defaults.otherBool) == Defaults.otherBool) // Required - success - #expect(try config.requiredBool(forKey: ConfigKey(["bool"])) == Defaults.bool) #expect(try config.requiredBool(forKey: "bool") == Defaults.bool) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredBool(forKey: ConfigKey(["absentBool"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredBool(forKey: "absentBool") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredBool(forKey: "absentBool") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredBool(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredBool(forKey: "failure") } } do { // Optional - success - #expect(config.bytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) #expect(config.bytes(forKey: "bytes") == Defaults.bytes) // Optional - missing - #expect(config.bytes(forKey: ConfigKey(["absentBytes"])) == nil) #expect(config.bytes(forKey: "absentBytes") == nil) // Optional - failing - #expect(config.bytes(forKey: ConfigKey(["failure"])) == nil) #expect(config.bytes(forKey: "failure") == nil) // Defaulted - success - #expect(config.bytes(forKey: ConfigKey(["bytes"]), default: Defaults.otherBytes) == Defaults.bytes) #expect(config.bytes(forKey: "bytes", default: Defaults.otherBytes) == Defaults.bytes) // Defaulted - missing - #expect( - config.bytes(forKey: ConfigKey(["absentBytes"]), default: Defaults.otherBytes) == Defaults.otherBytes - ) #expect(config.bytes(forKey: "absentBytes", default: Defaults.otherBytes) == Defaults.otherBytes) // Defaulted - failing - #expect(config.bytes(forKey: ConfigKey(["failure"]), default: Defaults.otherBytes) == Defaults.otherBytes) #expect(config.bytes(forKey: "failure", default: Defaults.otherBytes) == Defaults.otherBytes) // Required - success - #expect(try config.requiredBytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) #expect(try config.requiredBytes(forKey: "bytes") == Defaults.bytes) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredBytes(forKey: ConfigKey(["absentBytes"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredBytes(forKey: "absentBytes") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredBytes(forKey: "absentBytes") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredBytes(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredBytes(forKey: "failure") } } do { // Optional - success - #expect(config.stringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray) #expect(config.stringArray(forKey: "stringArray") == Defaults.stringArray) // Optional - missing - #expect(config.stringArray(forKey: ConfigKey(["absentStringArray"])) == nil) #expect(config.stringArray(forKey: "absentStringArray") == nil) // Optional - failing - #expect(config.stringArray(forKey: ConfigKey(["failure"])) == nil) #expect(config.stringArray(forKey: "failure") == nil) // Defaulted - success - #expect( - config.stringArray(forKey: ConfigKey(["stringArray"]), default: Defaults.otherStringArray) - == Defaults.stringArray - ) #expect( config.stringArray(forKey: "stringArray", default: Defaults.otherStringArray) == Defaults.stringArray ) // Defaulted - missing - #expect( - config.stringArray(forKey: ConfigKey(["absentStringArray"]), default: Defaults.otherStringArray) - == Defaults.otherStringArray - ) #expect( config.stringArray(forKey: "absentStringArray", default: Defaults.otherStringArray) == Defaults.otherStringArray ) // Defaulted - failing - #expect( - config.stringArray(forKey: ConfigKey(["failure"]), default: Defaults.otherStringArray) - == Defaults.otherStringArray - ) #expect( config.stringArray(forKey: "failure", default: Defaults.otherStringArray) == Defaults.otherStringArray ) // Required - success - #expect(try config.requiredStringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray) #expect(try config.requiredStringArray(forKey: "stringArray") == Defaults.stringArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredStringArray(forKey: ConfigKey(["absentStringArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: "absentStringArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredStringArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try config.requiredStringArray(forKey: "failure") } } do { // Optional - success - #expect(config.intArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) #expect(config.intArray(forKey: "intArray") == Defaults.intArray) // Optional - missing - #expect(config.intArray(forKey: ConfigKey(["absentIntArray"])) == nil) #expect(config.intArray(forKey: "absentIntArray") == nil) // Optional - failing - #expect(config.intArray(forKey: ConfigKey(["failure"])) == nil) #expect(config.intArray(forKey: "failure") == nil) // Defaulted - success - #expect( - config.intArray(forKey: ConfigKey(["intArray"]), default: Defaults.otherIntArray) == Defaults.intArray - ) #expect(config.intArray(forKey: "intArray", default: Defaults.otherIntArray) == Defaults.intArray) // Defaulted - missing - #expect( - config.intArray(forKey: ConfigKey(["absentIntArray"]), default: Defaults.otherIntArray) - == Defaults.otherIntArray - ) #expect( config.intArray(forKey: "absentIntArray", default: Defaults.otherIntArray) == Defaults.otherIntArray ) // Defaulted - failing - #expect( - config.intArray(forKey: ConfigKey(["failure"]), default: Defaults.otherIntArray) - == Defaults.otherIntArray - ) #expect(config.intArray(forKey: "failure", default: Defaults.otherIntArray) == Defaults.otherIntArray) // Required - success - #expect(try config.requiredIntArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) #expect(try config.requiredIntArray(forKey: "intArray") == Defaults.intArray) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredIntArray(forKey: ConfigKey(["absentIntArray"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredIntArray(forKey: "absentIntArray") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredIntArray(forKey: "absentIntArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredIntArray(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.requiredIntArray(forKey: "failure") } } do { // Optional - success - #expect(config.doubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray) #expect(config.doubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Optional - missing - #expect(config.doubleArray(forKey: ConfigKey(["absentDoubleArray"])) == nil) #expect(config.doubleArray(forKey: "absentDoubleArray") == nil) // Optional - failing - #expect(config.doubleArray(forKey: ConfigKey(["failure"])) == nil) #expect(config.doubleArray(forKey: "failure") == nil) // Defaulted - success - #expect( - config.doubleArray(forKey: ConfigKey(["doubleArray"]), default: Defaults.otherDoubleArray) - == Defaults.doubleArray - ) #expect( config.doubleArray(forKey: "doubleArray", default: Defaults.otherDoubleArray) == Defaults.doubleArray ) // Defaulted - missing - #expect( - config.doubleArray(forKey: ConfigKey(["absentDoubleArray"]), default: Defaults.otherDoubleArray) - == Defaults.otherDoubleArray - ) #expect( config.doubleArray(forKey: "absentDoubleArray", default: Defaults.otherDoubleArray) == Defaults.otherDoubleArray ) // Defaulted - failing - #expect( - config.doubleArray(forKey: ConfigKey(["failure"]), default: Defaults.otherDoubleArray) - == Defaults.otherDoubleArray - ) #expect( config.doubleArray(forKey: "failure", default: Defaults.otherDoubleArray) == Defaults.otherDoubleArray ) // Required - success - #expect(try config.requiredDoubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray) #expect(try config.requiredDoubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredDoubleArray(forKey: ConfigKey(["absentDoubleArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredDoubleArray(forKey: "absentDoubleArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredDoubleArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try config.requiredDoubleArray(forKey: "failure") } } do { // Optional - success - #expect(config.boolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) #expect(config.boolArray(forKey: "boolArray") == Defaults.boolArray) // Optional - missing - #expect(config.boolArray(forKey: ConfigKey(["absentBoolArray"])) == nil) #expect(config.boolArray(forKey: "absentBoolArray") == nil) // Optional - failing - #expect(config.boolArray(forKey: ConfigKey(["failure"])) == nil) #expect(config.boolArray(forKey: "failure") == nil) // Defaulted - success - #expect( - config.boolArray(forKey: ConfigKey(["boolArray"]), default: Defaults.otherBoolArray) - == Defaults.boolArray - ) #expect(config.boolArray(forKey: "boolArray", default: Defaults.otherBoolArray) == Defaults.boolArray) // Defaulted - missing - #expect( - config.boolArray(forKey: ConfigKey(["absentBoolArray"]), default: Defaults.otherBoolArray) - == Defaults.otherBoolArray - ) #expect( config.boolArray(forKey: "absentBoolArray", default: Defaults.otherBoolArray) == Defaults.otherBoolArray ) // Defaulted - failing - #expect( - config.boolArray(forKey: ConfigKey(["failure"]), default: Defaults.otherBoolArray) - == Defaults.otherBoolArray - ) #expect(config.boolArray(forKey: "failure", default: Defaults.otherBoolArray) == Defaults.otherBoolArray) // Required - success - #expect(try config.requiredBoolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) #expect(try config.requiredBoolArray(forKey: "boolArray") == Defaults.boolArray) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try config.requiredBoolArray(forKey: ConfigKey(["absentBoolArray"])) - } + let error1 = #expect(throws: ConfigError.self) { try config.requiredBoolArray(forKey: "absentBoolArray") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredBoolArray(forKey: "absentBoolArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredBoolArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try config.requiredBoolArray(forKey: "failure") } } do { // Optional - success - #expect(config.byteChunkArray(forKey: ConfigKey(["byteChunkArray"])) == Defaults.byteChunkArray) #expect(config.byteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Optional - missing - #expect(config.byteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) == nil) #expect(config.byteChunkArray(forKey: "absentByteChunkArray") == nil) // Optional - failing - #expect(config.byteChunkArray(forKey: ConfigKey(["failure"])) == nil) #expect(config.byteChunkArray(forKey: "failure") == nil) // Defaulted - success - #expect( - config.byteChunkArray(forKey: ConfigKey(["byteChunkArray"]), default: Defaults.otherByteChunkArray) - == Defaults.byteChunkArray - ) #expect( config.byteChunkArray(forKey: "byteChunkArray", default: Defaults.otherByteChunkArray) == Defaults.byteChunkArray ) // Defaulted - missing - #expect( - config.byteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - default: Defaults.otherByteChunkArray - ) == Defaults.otherByteChunkArray - ) #expect( config.byteChunkArray(forKey: "absentByteChunkArray", default: Defaults.otherByteChunkArray) == Defaults.otherByteChunkArray ) // Defaulted - failing - #expect( - config.byteChunkArray(forKey: ConfigKey(["failure"]), default: Defaults.otherByteChunkArray) - == Defaults.otherByteChunkArray - ) #expect( config.byteChunkArray(forKey: "failure", default: Defaults.otherByteChunkArray) == Defaults.otherByteChunkArray ) // Required - success - #expect(try config.requiredByteChunkArray(forKey: ConfigKey(["byteChunkArray"])) == Defaults.byteChunkArray) #expect(try config.requiredByteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredByteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredByteChunkArray(forKey: "absentByteChunkArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredByteChunkArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try config.requiredByteChunkArray(forKey: "failure") } } } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift.gyb index 97c0818..686cd34 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet1.swift.gyb @@ -35,41 +35,31 @@ struct ConfigReaderMethodTestsGet1 { % lower_name = lower_first(name) do { // Optional - success - #expect(config.${lower_name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) #expect(config.${lower_name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Optional - missing - #expect(config.${lower_name}(forKey: ConfigKey(["absent${name}"])) == nil) #expect(config.${lower_name}(forKey: "absent${name}") == nil) // Optional - failing - #expect(config.${lower_name}(forKey: ConfigKey(["failure"])) == nil) #expect(config.${lower_name}(forKey: "failure") == nil) // Defaulted - success - #expect(config.${lower_name}(forKey: ConfigKey(["${lower_name}"]), default: Defaults.other${name}) == Defaults.${lower_name}) #expect(config.${lower_name}(forKey: "${lower_name}", default: Defaults.other${name}) == Defaults.${lower_name}) // Defaulted - missing - #expect(config.${lower_name}(forKey: ConfigKey(["absent${name}"]), default: Defaults.other${name}) == Defaults.other${name}) #expect(config.${lower_name}(forKey: "absent${name}", default: Defaults.other${name}) == Defaults.other${name}) // Defaulted - failing - #expect(config.${lower_name}(forKey: ConfigKey(["failure"]), default: Defaults.other${name}) == Defaults.other${name}) #expect(config.${lower_name}(forKey: "failure", default: Defaults.other${name}) == Defaults.other${name}) // Required - success - #expect(try config.required${name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) #expect(try config.required${name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try config.required${name}(forKey: ConfigKey(["absent${name}"])) } + let error1 = #expect(throws: ConfigError.self) { try config.required${name}(forKey: "absent${name}") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) - let error2 = #expect(throws: ConfigError.self) { try config.required${name}(forKey: "absent${name}") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.required${name}(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try config.required${name}(forKey: "failure") } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift index 0c4186e..807e2ff 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift @@ -34,32 +34,17 @@ struct ConfigReaderMethodTestsGet2 { do { // Optional - success - #expect( - config.string(forKey: ConfigKey(["stringConvertible"]), as: TestStringConvertible.self) - == Defaults.stringConvertible - ) #expect( config.string(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible ) // Optional - missing - #expect( - config.string(forKey: ConfigKey(["absentStringConvertible"]), as: TestStringConvertible.self) == nil - ) #expect(config.string(forKey: "absentStringConvertible", as: TestStringConvertible.self) == nil) // Optional - failing - #expect(config.string(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) == nil) #expect(config.string(forKey: "failure", as: TestStringConvertible.self) == nil) // Defaulted - success - #expect( - config.string( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.stringConvertible - ) #expect( config.string( forKey: "stringConvertible", @@ -69,13 +54,6 @@ struct ConfigReaderMethodTestsGet2 { ) // Defaulted - missing - #expect( - config.string( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.otherStringConvertible - ) #expect( config.string( forKey: "absentStringConvertible", @@ -85,13 +63,6 @@ struct ConfigReaderMethodTestsGet2 { ) // Defaulted - failing - #expect( - config.string( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.otherStringConvertible - ) #expect( config.string( forKey: "failure", @@ -101,10 +72,6 @@ struct ConfigReaderMethodTestsGet2 { ) // Required - success - #expect( - try config.requiredString(forKey: ConfigKey(["stringConvertible"]), as: TestStringConvertible.self) - == Defaults.stringConvertible - ) #expect( try config.requiredString(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible @@ -112,91 +79,53 @@ struct ConfigReaderMethodTestsGet2 { // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absentStringConvertible", as: TestStringConvertible.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredString(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: "failure", as: TestStringConvertible.self) } } do { // Optional - success - #expect(config.string(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) == Defaults.stringEnum) #expect(config.string(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum) // Optional - missing - #expect(config.string(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) == nil) #expect(config.string(forKey: "absentStringEnum", as: TestEnum.self) == nil) // Optional - failing - #expect(config.string(forKey: ConfigKey(["failure"]), as: TestEnum.self) == nil) #expect(config.string(forKey: "failure", as: TestEnum.self) == nil) // Defaulted - success - #expect( - config.string(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self, default: Defaults.otherStringEnum) - == Defaults.stringEnum - ) #expect( config.string(forKey: "stringEnum", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.stringEnum ) // Defaulted - missing - #expect( - config.string( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum - ) == Defaults.otherStringEnum - ) #expect( config.string(forKey: "absentStringEnum", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.otherStringEnum ) // Defaulted - failing - #expect( - config.string(forKey: ConfigKey(["failure"]), as: TestEnum.self, default: Defaults.otherStringEnum) - == Defaults.otherStringEnum - ) #expect( config.string(forKey: "failure", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.otherStringEnum ) // Required - success - #expect( - try config.requiredString(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) == Defaults.stringEnum - ) #expect(try config.requiredString(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredString(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absentStringEnum", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredString(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift.gyb index befe699..52f46ba 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet2.swift.gyb @@ -36,41 +36,31 @@ struct ConfigReaderMethodTestsGet2 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(config.string(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(config.string(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(config.string(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(config.string(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - #expect(config.string(forKey: ConfigKey(["failure"]), as: ${test_type}.self) == nil) #expect(config.string(forKey: "failure", as: ${test_type}.self) == nil) // Defaulted - success - #expect(config.string(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(config.string(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(config.string(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(config.string(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(config.string(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(config.string(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Required - success - #expect(try config.requiredString(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try config.requiredString(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredString(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } #expect(throws: TestProvider.TestError.self) { try config.requiredString(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift index a4b256a..680be2e 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift @@ -34,34 +34,18 @@ struct ConfigReaderMethodTestsGet3 { do { // Optional - success - #expect( - config.stringArray(forKey: ConfigKey(["stringConvertibleArray"]), as: TestStringConvertible.self) - == Defaults.stringConvertibleArray - ) #expect( config.stringArray(forKey: "stringConvertibleArray", as: TestStringConvertible.self) == Defaults.stringConvertibleArray ) // Optional - missing - #expect( - config.stringArray(forKey: ConfigKey(["absentStringConvertibleArray"]), as: TestStringConvertible.self) - == nil - ) #expect(config.stringArray(forKey: "absentStringConvertibleArray", as: TestStringConvertible.self) == nil) // Optional - failing - #expect(config.stringArray(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) == nil) #expect(config.stringArray(forKey: "failure", as: TestStringConvertible.self) == nil) // Defaulted - success - #expect( - config.stringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.stringConvertibleArray - ) #expect( config.stringArray( forKey: "stringConvertibleArray", @@ -71,13 +55,6 @@ struct ConfigReaderMethodTestsGet3 { ) // Defaulted - missing - #expect( - config.stringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.otherStringConvertibleArray - ) #expect( config.stringArray( forKey: "absentStringConvertibleArray", @@ -87,13 +64,6 @@ struct ConfigReaderMethodTestsGet3 { ) // Defaulted - failing - #expect( - config.stringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.otherStringConvertibleArray - ) #expect( config.stringArray( forKey: "failure", @@ -103,12 +73,6 @@ struct ConfigReaderMethodTestsGet3 { ) // Required - success - #expect( - try config.requiredStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self - ) == Defaults.stringConvertibleArray - ) #expect( try config.requiredStringArray(forKey: "stringConvertibleArray", as: TestStringConvertible.self) == Defaults.stringConvertibleArray @@ -116,62 +80,32 @@ struct ConfigReaderMethodTestsGet3 { // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: "absentStringConvertibleArray", as: TestStringConvertible.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredStringArray(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } #expect(throws: TestProvider.TestError.self) { try config.requiredStringArray(forKey: "failure", as: TestStringConvertible.self) } } do { // Optional - success - #expect( - config.stringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) #expect(config.stringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray) // Optional - missing - #expect(config.stringArray(forKey: ConfigKey(["absentStringEnumArray"]), as: TestEnum.self) == nil) #expect(config.stringArray(forKey: "absentStringEnumArray", as: TestEnum.self) == nil) // Optional - failing - #expect(config.stringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) == nil) #expect(config.stringArray(forKey: "failure", as: TestEnum.self) == nil) // Defaulted - success - #expect( - config.stringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.stringEnumArray - ) #expect( config.stringArray(forKey: "stringEnumArray", as: TestEnum.self, default: Defaults.otherStringEnumArray) == Defaults.stringEnumArray ) // Defaulted - missing - #expect( - config.stringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.otherStringEnumArray - ) #expect( config.stringArray( forKey: "absentStringEnumArray", @@ -181,41 +115,23 @@ struct ConfigReaderMethodTestsGet3 { ) // Defaulted - failing - #expect( - config.stringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.otherStringEnumArray - ) #expect( config.stringArray(forKey: "failure", as: TestEnum.self, default: Defaults.otherStringEnumArray) == Defaults.otherStringEnumArray ) // Required - success - #expect( - try config.requiredStringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) #expect( try config.requiredStringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray ) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try config.requiredStringArray(forKey: ConfigKey(["absentStringEnumArray"]), as: TestEnum.self) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: "absentStringEnumArray", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try config.requiredStringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } #expect(throws: TestProvider.TestError.self) { try config.requiredStringArray(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift.gyb index 3562580..a116103 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsGet3.swift.gyb @@ -36,41 +36,31 @@ struct ConfigReaderMethodTestsGet3 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(config.stringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(config.stringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(config.stringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(config.stringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - #expect(config.stringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self) == nil) #expect(config.stringArray(forKey: "failure", as: ${test_type}.self) == nil) // Defaulted - success - #expect(config.stringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(config.stringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(config.stringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(config.stringArray(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(config.stringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(config.stringArray(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Required - success - #expect(try config.requiredStringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(try config.requiredStringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = #expect(throws: ConfigError.self) { try config.requiredStringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try config.requiredStringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } #expect(throws: TestProvider.TestError.self) { try config.requiredStringArray(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift index 7f51f08..3941f0a 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift @@ -36,33 +36,15 @@ struct ConfigReaderMethodTestsWatch1 { do { // Optional - success - #expect( - try await config.watchString(forKey: ConfigKey(["string"]), updatesHandler: awaitFirst) - == Defaults.string - ) #expect(try await config.watchString(forKey: "string", updatesHandler: awaitFirst) == Defaults.string) // Optional - missing - #expect( - try await config.watchString(forKey: ConfigKey(["absentString"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchString(forKey: "absentString", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect( - try await config.watchString(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchString(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchString( - forKey: ConfigKey(["string"]), - default: Defaults.otherString, - updatesHandler: awaitFirst - ) == Defaults.string - ) #expect( try await config.watchString( forKey: "string", @@ -72,13 +54,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchString( - forKey: ConfigKey(["absentString"]), - default: Defaults.otherString, - updatesHandler: awaitFirst - ) == Defaults.otherString - ) #expect( try await config.watchString( forKey: "absentString", @@ -88,13 +63,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchString( - forKey: ConfigKey(["failure"]), - default: Defaults.otherString, - updatesHandler: awaitFirst - ) == Defaults.otherString - ) #expect( try await config.watchString( forKey: "failure", @@ -104,140 +72,74 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredString(forKey: ConfigKey(["string"]), updatesHandler: awaitFirst) - == Defaults.string - ) #expect( try await config.watchRequiredString(forKey: "string", updatesHandler: awaitFirst) == Defaults.string ) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredString(forKey: ConfigKey(["absentString"]), updatesHandler: awaitFirst) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredString(forKey: "absentString", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredString(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredString(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect(try await config.watchInt(forKey: ConfigKey(["int"]), updatesHandler: awaitFirst) == Defaults.int) #expect(try await config.watchInt(forKey: "int", updatesHandler: awaitFirst) == Defaults.int) // Optional - missing - #expect( - try await config.watchInt(forKey: ConfigKey(["absentInt"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchInt(forKey: "absentInt", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect(try await config.watchInt(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watchInt(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchInt( - forKey: ConfigKey(["int"]), - default: Defaults.otherInt, - updatesHandler: awaitFirst - ) == Defaults.int - ) #expect( try await config.watchInt(forKey: "int", default: Defaults.otherInt, updatesHandler: awaitFirst) == Defaults.int ) // Defaulted - missing - #expect( - try await config.watchInt( - forKey: ConfigKey(["absentInt"]), - default: Defaults.otherInt, - updatesHandler: awaitFirst - ) == Defaults.otherInt - ) #expect( try await config.watchInt(forKey: "absentInt", default: Defaults.otherInt, updatesHandler: awaitFirst) == Defaults.otherInt ) // Defaulted - failing - #expect( - try await config.watchInt( - forKey: ConfigKey(["failure"]), - default: Defaults.otherInt, - updatesHandler: awaitFirst - ) == Defaults.otherInt - ) #expect( try await config.watchInt(forKey: "failure", default: Defaults.otherInt, updatesHandler: awaitFirst) == Defaults.otherInt ) // Required - success - #expect( - try await config.watchRequiredInt(forKey: ConfigKey(["int"]), updatesHandler: awaitFirst) - == Defaults.int - ) #expect(try await config.watchRequiredInt(forKey: "int", updatesHandler: awaitFirst) == Defaults.int) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredInt(forKey: ConfigKey(["absentInt"]), updatesHandler: awaitFirst) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredInt(forKey: "absentInt", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredInt(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredInt(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchDouble(forKey: ConfigKey(["double"]), updatesHandler: awaitFirst) - == Defaults.double - ) #expect(try await config.watchDouble(forKey: "double", updatesHandler: awaitFirst) == Defaults.double) // Optional - missing - #expect( - try await config.watchDouble(forKey: ConfigKey(["absentDouble"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchDouble(forKey: "absentDouble", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect( - try await config.watchDouble(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchDouble(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchDouble( - forKey: ConfigKey(["double"]), - default: Defaults.otherDouble, - updatesHandler: awaitFirst - ) == Defaults.double - ) #expect( try await config.watchDouble( forKey: "double", @@ -247,13 +149,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchDouble( - forKey: ConfigKey(["absentDouble"]), - default: Defaults.otherDouble, - updatesHandler: awaitFirst - ) == Defaults.otherDouble - ) #expect( try await config.watchDouble( forKey: "absentDouble", @@ -263,13 +158,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchDouble( - forKey: ConfigKey(["failure"]), - default: Defaults.otherDouble, - updatesHandler: awaitFirst - ) == Defaults.otherDouble - ) #expect( try await config.watchDouble( forKey: "failure", @@ -279,72 +167,38 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredDouble(forKey: ConfigKey(["double"]), updatesHandler: awaitFirst) - == Defaults.double - ) #expect( try await config.watchRequiredDouble(forKey: "double", updatesHandler: awaitFirst) == Defaults.double ) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredDouble(forKey: ConfigKey(["absentDouble"]), updatesHandler: awaitFirst) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredDouble(forKey: "absentDouble", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredDouble(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredDouble(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchBool(forKey: ConfigKey(["bool"]), updatesHandler: awaitFirst) == Defaults.bool - ) #expect(try await config.watchBool(forKey: "bool", updatesHandler: awaitFirst) == Defaults.bool) // Optional - missing - #expect( - try await config.watchBool(forKey: ConfigKey(["absentBool"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchBool(forKey: "absentBool", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect( - try await config.watchBool(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchBool(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchBool( - forKey: ConfigKey(["bool"]), - default: Defaults.otherBool, - updatesHandler: awaitFirst - ) == Defaults.bool - ) #expect( try await config.watchBool(forKey: "bool", default: Defaults.otherBool, updatesHandler: awaitFirst) == Defaults.bool ) // Defaulted - missing - #expect( - try await config.watchBool( - forKey: ConfigKey(["absentBool"]), - default: Defaults.otherBool, - updatesHandler: awaitFirst - ) == Defaults.otherBool - ) #expect( try await config.watchBool( forKey: "absentBool", @@ -354,84 +208,42 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchBool( - forKey: ConfigKey(["failure"]), - default: Defaults.otherBool, - updatesHandler: awaitFirst - ) == Defaults.otherBool - ) #expect( try await config.watchBool(forKey: "failure", default: Defaults.otherBool, updatesHandler: awaitFirst) == Defaults.otherBool ) // Required - success - #expect( - try await config.watchRequiredBool(forKey: ConfigKey(["bool"]), updatesHandler: awaitFirst) - == Defaults.bool - ) #expect(try await config.watchRequiredBool(forKey: "bool", updatesHandler: awaitFirst) == Defaults.bool) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredBool(forKey: ConfigKey(["absentBool"]), updatesHandler: awaitFirst) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredBool(forKey: "absentBool", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredBool(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredBool(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchBytes(forKey: ConfigKey(["bytes"]), updatesHandler: awaitFirst) == Defaults.bytes - ) #expect(try await config.watchBytes(forKey: "bytes", updatesHandler: awaitFirst) == Defaults.bytes) // Optional - missing - #expect( - try await config.watchBytes(forKey: ConfigKey(["absentBytes"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchBytes(forKey: "absentBytes", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect( - try await config.watchBytes(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchBytes(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchBytes( - forKey: ConfigKey(["bytes"]), - default: Defaults.otherBytes, - updatesHandler: awaitFirst - ) == Defaults.bytes - ) #expect( try await config.watchBytes(forKey: "bytes", default: Defaults.otherBytes, updatesHandler: awaitFirst) == Defaults.bytes ) // Defaulted - missing - #expect( - try await config.watchBytes( - forKey: ConfigKey(["absentBytes"]), - default: Defaults.otherBytes, - updatesHandler: awaitFirst - ) == Defaults.otherBytes - ) #expect( try await config.watchBytes( forKey: "absentBytes", @@ -441,78 +253,41 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchBytes( - forKey: ConfigKey(["failure"]), - default: Defaults.otherBytes, - updatesHandler: awaitFirst - ) == Defaults.otherBytes - ) #expect( try await config.watchBytes(forKey: "failure", default: Defaults.otherBytes, updatesHandler: awaitFirst) == Defaults.otherBytes ) // Required - success - #expect( - try await config.watchRequiredBytes(forKey: ConfigKey(["bytes"]), updatesHandler: awaitFirst) - == Defaults.bytes - ) #expect(try await config.watchRequiredBytes(forKey: "bytes", updatesHandler: awaitFirst) == Defaults.bytes) // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredBytes(forKey: ConfigKey(["absentBytes"]), updatesHandler: awaitFirst) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredBytes(forKey: "absentBytes", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredBytes(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredBytes(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchStringArray(forKey: ConfigKey(["stringArray"]), updatesHandler: awaitFirst) - == Defaults.stringArray - ) #expect( try await config.watchStringArray(forKey: "stringArray", updatesHandler: awaitFirst) == Defaults.stringArray ) // Optional - missing - #expect( - try await config.watchStringArray(forKey: ConfigKey(["absentStringArray"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect( try await config.watchStringArray(forKey: "absentStringArray", updatesHandler: awaitFirst) == .some(nil) ) // Optional - failing - #expect( - try await config.watchStringArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchStringArray(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["stringArray"]), - default: Defaults.otherStringArray, - updatesHandler: awaitFirst - ) == Defaults.stringArray - ) #expect( try await config.watchStringArray( forKey: "stringArray", @@ -522,13 +297,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["absentStringArray"]), - default: Defaults.otherStringArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringArray - ) #expect( try await config.watchStringArray( forKey: "absentStringArray", @@ -538,13 +306,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherStringArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringArray - ) #expect( try await config.watchStringArray( forKey: "failure", @@ -554,12 +315,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredStringArray( - forKey: ConfigKey(["stringArray"]), - updatesHandler: awaitFirst - ) == Defaults.stringArray - ) #expect( try await config.watchRequiredStringArray(forKey: "stringArray", updatesHandler: awaitFirst) == Defaults.stringArray @@ -567,54 +322,26 @@ struct ConfigReaderMethodTestsWatch1 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredStringArray( - forKey: ConfigKey(["absentStringArray"]), - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredStringArray(forKey: "absentStringArray", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredStringArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredStringArray(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchIntArray(forKey: ConfigKey(["intArray"]), updatesHandler: awaitFirst) - == Defaults.intArray - ) #expect(try await config.watchIntArray(forKey: "intArray", updatesHandler: awaitFirst) == Defaults.intArray) // Optional - missing - #expect( - try await config.watchIntArray(forKey: ConfigKey(["absentIntArray"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchIntArray(forKey: "absentIntArray", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect( - try await config.watchIntArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil) - ) #expect(try await config.watchIntArray(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchIntArray( - forKey: ConfigKey(["intArray"]), - default: Defaults.otherIntArray, - updatesHandler: awaitFirst - ) == Defaults.intArray - ) #expect( try await config.watchIntArray( forKey: "intArray", @@ -624,13 +351,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchIntArray( - forKey: ConfigKey(["absentIntArray"]), - default: Defaults.otherIntArray, - updatesHandler: awaitFirst - ) == Defaults.otherIntArray - ) #expect( try await config.watchIntArray( forKey: "absentIntArray", @@ -640,13 +360,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchIntArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherIntArray, - updatesHandler: awaitFirst - ) == Defaults.otherIntArray - ) #expect( try await config.watchIntArray( forKey: "failure", @@ -656,10 +369,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredIntArray(forKey: ConfigKey(["intArray"]), updatesHandler: awaitFirst) - == Defaults.intArray - ) #expect( try await config.watchRequiredIntArray(forKey: "intArray", updatesHandler: awaitFirst) == Defaults.intArray @@ -667,60 +376,31 @@ struct ConfigReaderMethodTestsWatch1 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredIntArray( - forKey: ConfigKey(["absentIntArray"]), - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredIntArray(forKey: "absentIntArray", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredIntArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredIntArray(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchDoubleArray(forKey: ConfigKey(["doubleArray"]), updatesHandler: awaitFirst) - == Defaults.doubleArray - ) #expect( try await config.watchDoubleArray(forKey: "doubleArray", updatesHandler: awaitFirst) == Defaults.doubleArray ) // Optional - missing - #expect( - try await config.watchDoubleArray(forKey: ConfigKey(["absentDoubleArray"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect( try await config.watchDoubleArray(forKey: "absentDoubleArray", updatesHandler: awaitFirst) == .some(nil) ) // Optional - failing - #expect( - try await config.watchDoubleArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchDoubleArray(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchDoubleArray( - forKey: ConfigKey(["doubleArray"]), - default: Defaults.otherDoubleArray, - updatesHandler: awaitFirst - ) == Defaults.doubleArray - ) #expect( try await config.watchDoubleArray( forKey: "doubleArray", @@ -730,13 +410,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchDoubleArray( - forKey: ConfigKey(["absentDoubleArray"]), - default: Defaults.otherDoubleArray, - updatesHandler: awaitFirst - ) == Defaults.otherDoubleArray - ) #expect( try await config.watchDoubleArray( forKey: "absentDoubleArray", @@ -746,13 +419,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchDoubleArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherDoubleArray, - updatesHandler: awaitFirst - ) == Defaults.otherDoubleArray - ) #expect( try await config.watchDoubleArray( forKey: "failure", @@ -762,12 +428,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredDoubleArray( - forKey: ConfigKey(["doubleArray"]), - updatesHandler: awaitFirst - ) == Defaults.doubleArray - ) #expect( try await config.watchRequiredDoubleArray(forKey: "doubleArray", updatesHandler: awaitFirst) == Defaults.doubleArray @@ -775,59 +435,30 @@ struct ConfigReaderMethodTestsWatch1 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredDoubleArray( - forKey: ConfigKey(["absentDoubleArray"]), - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredDoubleArray(forKey: "absentDoubleArray", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredDoubleArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredDoubleArray(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchBoolArray(forKey: ConfigKey(["boolArray"]), updatesHandler: awaitFirst) - == Defaults.boolArray - ) #expect( try await config.watchBoolArray(forKey: "boolArray", updatesHandler: awaitFirst) == Defaults.boolArray ) // Optional - missing - #expect( - try await config.watchBoolArray(forKey: ConfigKey(["absentBoolArray"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect( try await config.watchBoolArray(forKey: "absentBoolArray", updatesHandler: awaitFirst) == .some(nil) ) // Optional - failing - #expect( - try await config.watchBoolArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchBoolArray(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchBoolArray( - forKey: ConfigKey(["boolArray"]), - default: Defaults.otherBoolArray, - updatesHandler: awaitFirst - ) == Defaults.boolArray - ) #expect( try await config.watchBoolArray( forKey: "boolArray", @@ -837,13 +468,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchBoolArray( - forKey: ConfigKey(["absentBoolArray"]), - default: Defaults.otherBoolArray, - updatesHandler: awaitFirst - ) == Defaults.otherBoolArray - ) #expect( try await config.watchBoolArray( forKey: "absentBoolArray", @@ -853,13 +477,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchBoolArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherBoolArray, - updatesHandler: awaitFirst - ) == Defaults.otherBoolArray - ) #expect( try await config.watchBoolArray( forKey: "failure", @@ -869,10 +486,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredBoolArray(forKey: ConfigKey(["boolArray"]), updatesHandler: awaitFirst) - == Defaults.boolArray - ) #expect( try await config.watchRequiredBoolArray(forKey: "boolArray", updatesHandler: awaitFirst) == Defaults.boolArray @@ -880,63 +493,32 @@ struct ConfigReaderMethodTestsWatch1 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredBoolArray( - forKey: ConfigKey(["absentBoolArray"]), - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredBoolArray(forKey: "absentBoolArray", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredBoolArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredBoolArray(forKey: "failure", updatesHandler: awaitFirst) } } do { // Optional - success - #expect( - try await config.watchByteChunkArray(forKey: ConfigKey(["byteChunkArray"]), updatesHandler: awaitFirst) - == Defaults.byteChunkArray - ) #expect( try await config.watchByteChunkArray(forKey: "byteChunkArray", updatesHandler: awaitFirst) == Defaults.byteChunkArray ) // Optional - missing - #expect( - try await config.watchByteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchByteChunkArray(forKey: "absentByteChunkArray", updatesHandler: awaitFirst) == .some(nil) ) // Optional - failing - #expect( - try await config.watchByteChunkArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - == .some(nil) - ) #expect(try await config.watchByteChunkArray(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect( - try await config.watchByteChunkArray( - forKey: ConfigKey(["byteChunkArray"]), - default: Defaults.otherByteChunkArray, - updatesHandler: awaitFirst - ) == Defaults.byteChunkArray - ) #expect( try await config.watchByteChunkArray( forKey: "byteChunkArray", @@ -946,13 +528,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - missing - #expect( - try await config.watchByteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - default: Defaults.otherByteChunkArray, - updatesHandler: awaitFirst - ) == Defaults.otherByteChunkArray - ) #expect( try await config.watchByteChunkArray( forKey: "absentByteChunkArray", @@ -962,13 +537,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Defaulted - failing - #expect( - try await config.watchByteChunkArray( - forKey: ConfigKey(["failure"]), - default: Defaults.otherByteChunkArray, - updatesHandler: awaitFirst - ) == Defaults.otherByteChunkArray - ) #expect( try await config.watchByteChunkArray( forKey: "failure", @@ -978,12 +546,6 @@ struct ConfigReaderMethodTestsWatch1 { ) // Required - success - #expect( - try await config.watchRequiredByteChunkArray( - forKey: ConfigKey(["byteChunkArray"]), - updatesHandler: awaitFirst - ) == Defaults.byteChunkArray - ) #expect( try await config.watchRequiredByteChunkArray(forKey: "byteChunkArray", updatesHandler: awaitFirst) == Defaults.byteChunkArray @@ -991,21 +553,11 @@ struct ConfigReaderMethodTestsWatch1 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredByteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredByteChunkArray(forKey: "absentByteChunkArray", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredByteChunkArray(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredByteChunkArray(forKey: "failure", updatesHandler: awaitFirst) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift.gyb index 451cec9..587b805 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch1.swift.gyb @@ -36,41 +36,31 @@ struct ConfigReaderMethodTestsWatch1 { % lower_name = lower_first(name) do { // Optional - success - #expect(try await config.watch${name}(forKey: ConfigKey(["${lower_name}"]), updatesHandler: awaitFirst) == Defaults.${lower_name}) #expect(try await config.watch${name}(forKey: "${lower_name}", updatesHandler: awaitFirst) == Defaults.${lower_name}) // Optional - missing - #expect(try await config.watch${name}(forKey: ConfigKey(["absent${name}"]), updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${name}(forKey: "absent${name}", updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect(try await config.watch${name}(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${name}(forKey: "failure", updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect(try await config.watch${name}(forKey: ConfigKey(["${lower_name}"]), default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.${lower_name}) #expect(try await config.watch${name}(forKey: "${lower_name}", default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.${lower_name}) // Defaulted - missing - #expect(try await config.watch${name}(forKey: ConfigKey(["absent${name}"]), default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.other${name}) #expect(try await config.watch${name}(forKey: "absent${name}", default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.other${name}) // Defaulted - failing - #expect(try await config.watch${name}(forKey: ConfigKey(["failure"]), default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.other${name}) #expect(try await config.watch${name}(forKey: "failure", default: Defaults.other${name}, updatesHandler: awaitFirst) == Defaults.other${name}) // Required - success - #expect(try await config.watchRequired${name}(forKey: ConfigKey(["${lower_name}"]), updatesHandler: awaitFirst) == Defaults.${lower_name}) #expect(try await config.watchRequired${name}(forKey: "${lower_name}", updatesHandler: awaitFirst) == Defaults.${lower_name}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${name}(forKey: ConfigKey(["absent${name}"]), updatesHandler: awaitFirst) } + let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${name}(forKey: "absent${name}", updatesHandler: awaitFirst) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequired${name}(forKey: "absent${name}", updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${name}(forKey: ConfigKey(["failure"]), updatesHandler: awaitFirst) } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${name}(forKey: "failure", updatesHandler: awaitFirst) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift index b0d9f67..ee2543c 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift @@ -36,13 +36,6 @@ struct ConfigReaderMethodTestsWatch2 { do { // Optional - success - #expect( - try await config.watchString( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == Defaults.stringConvertible - ) #expect( try await config.watchString( forKey: "stringConvertible", @@ -52,13 +45,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Optional - missing - #expect( - try await config.watchString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchString( forKey: "absentStringConvertible", @@ -68,13 +54,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Optional - failing - #expect( - try await config.watchString( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchString( forKey: "failure", @@ -84,14 +63,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Defaulted - success - #expect( - try await config.watchString( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible, - updatesHandler: awaitFirst - ) == Defaults.stringConvertible - ) #expect( try await config.watchString( forKey: "stringConvertible", @@ -102,14 +73,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Defaulted - missing - #expect( - try await config.watchString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible, - updatesHandler: awaitFirst - ) == Defaults.otherStringConvertible - ) #expect( try await config.watchString( forKey: "absentStringConvertible", @@ -120,14 +83,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Defaulted - failing - #expect( - try await config.watchString( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible, - updatesHandler: awaitFirst - ) == Defaults.otherStringConvertible - ) #expect( try await config.watchString( forKey: "failure", @@ -138,13 +93,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Required - success - #expect( - try await config.watchRequiredString( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == Defaults.stringConvertible - ) #expect( try await config.watchRequiredString( forKey: "stringConvertible", @@ -155,30 +103,15 @@ struct ConfigReaderMethodTestsWatch2 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredString( forKey: "absentStringConvertible", as: TestStringConvertible.self, updatesHandler: awaitFirst ) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredString( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredString( forKey: "failure", @@ -189,53 +122,24 @@ struct ConfigReaderMethodTestsWatch2 { } do { // Optional - success - #expect( - try await config.watchString( - forKey: ConfigKey(["stringEnum"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == Defaults.stringEnum - ) #expect( try await config.watchString(forKey: "stringEnum", as: TestEnum.self, updatesHandler: awaitFirst) == Defaults.stringEnum ) // Optional - missing - #expect( - try await config.watchString( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchString(forKey: "absentStringEnum", as: TestEnum.self, updatesHandler: awaitFirst) == .some(nil) ) // Optional - failing - #expect( - try await config.watchString( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchString(forKey: "failure", as: TestEnum.self, updatesHandler: awaitFirst) == .some(nil) ) // Defaulted - success - #expect( - try await config.watchString( - forKey: ConfigKey(["stringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum, - updatesHandler: awaitFirst - ) == Defaults.stringEnum - ) #expect( try await config.watchString( forKey: "stringEnum", @@ -246,14 +150,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Defaulted - missing - #expect( - try await config.watchString( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum, - updatesHandler: awaitFirst - ) == Defaults.otherStringEnum - ) #expect( try await config.watchString( forKey: "absentStringEnum", @@ -264,14 +160,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Defaulted - failing - #expect( - try await config.watchString( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnum, - updatesHandler: awaitFirst - ) == Defaults.otherStringEnum - ) #expect( try await config.watchString( forKey: "failure", @@ -282,13 +170,6 @@ struct ConfigReaderMethodTestsWatch2 { ) // Required - success - #expect( - try await config.watchRequiredString( - forKey: ConfigKey(["stringEnum"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == Defaults.stringEnum - ) #expect( try await config.watchRequiredString( forKey: "stringEnum", @@ -299,30 +180,15 @@ struct ConfigReaderMethodTestsWatch2 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredString( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredString( forKey: "absentStringEnum", as: TestEnum.self, updatesHandler: awaitFirst ) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredString( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredString(forKey: "failure", as: TestEnum.self, updatesHandler: awaitFirst) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift.gyb index 0a8b188..f11f38c 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch2.swift.gyb @@ -38,41 +38,31 @@ struct ConfigReaderMethodTestsWatch2 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(try await config.watch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${suffix}(forKey: "failure", as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect(try await config.watch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) #expect(try await config.watch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) #expect(try await config.watch${suffix}(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) // Required - success - #expect(try await config.watchRequired${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watchRequired${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) } + let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, updatesHandler: awaitFirst) } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${suffix}(forKey: "failure", as: ${test_type}.self, updatesHandler: awaitFirst) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift index b493e55..094742f 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift @@ -36,13 +36,6 @@ struct ConfigReaderMethodTestsWatch3 { do { // Optional - success - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == Defaults.stringConvertibleArray - ) #expect( try await config.watchStringArray( forKey: "stringConvertibleArray", @@ -52,13 +45,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Optional - missing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchStringArray( forKey: "absentStringConvertibleArray", @@ -68,13 +54,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Optional - failing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchStringArray( forKey: "failure", @@ -84,14 +63,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Defaulted - success - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray, - updatesHandler: awaitFirst - ) == Defaults.stringConvertibleArray - ) #expect( try await config.watchStringArray( forKey: "stringConvertibleArray", @@ -102,14 +73,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Defaulted - missing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringConvertibleArray - ) #expect( try await config.watchStringArray( forKey: "absentStringConvertibleArray", @@ -120,14 +83,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Defaulted - failing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringConvertibleArray - ) #expect( try await config.watchStringArray( forKey: "failure", @@ -138,13 +93,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Required - success - #expect( - try await config.watchRequiredStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) == Defaults.stringConvertibleArray - ) #expect( try await config.watchRequiredStringArray( forKey: "stringConvertibleArray", @@ -155,30 +103,15 @@ struct ConfigReaderMethodTestsWatch3 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredStringArray( forKey: "absentStringConvertibleArray", as: TestStringConvertible.self, updatesHandler: awaitFirst ) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredStringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - updatesHandler: awaitFirst - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredStringArray( forKey: "failure", @@ -189,13 +122,6 @@ struct ConfigReaderMethodTestsWatch3 { } do { // Optional - success - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == Defaults.stringEnumArray - ) #expect( try await config.watchStringArray( forKey: "stringEnumArray", @@ -205,13 +131,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Optional - missing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchStringArray( forKey: "absentStringEnumArray", @@ -221,27 +140,12 @@ struct ConfigReaderMethodTestsWatch3 { ) // Optional - failing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == .some(nil) - ) #expect( try await config.watchStringArray(forKey: "failure", as: TestEnum.self, updatesHandler: awaitFirst) == .some(nil) ) // Defaulted - success - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray, - updatesHandler: awaitFirst - ) == Defaults.stringEnumArray - ) #expect( try await config.watchStringArray( forKey: "stringEnumArray", @@ -252,14 +156,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Defaulted - missing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringEnumArray - ) #expect( try await config.watchStringArray( forKey: "absentStringEnumArray", @@ -270,14 +166,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Defaulted - failing - #expect( - try await config.watchStringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray, - updatesHandler: awaitFirst - ) == Defaults.otherStringEnumArray - ) #expect( try await config.watchStringArray( forKey: "failure", @@ -288,13 +176,6 @@ struct ConfigReaderMethodTestsWatch3 { ) // Required - success - #expect( - try await config.watchRequiredStringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) == Defaults.stringEnumArray - ) #expect( try await config.watchRequiredStringArray( forKey: "stringEnumArray", @@ -305,30 +186,15 @@ struct ConfigReaderMethodTestsWatch3 { // Required - missing let error1 = await #expect(throws: ConfigError.self) { - try await config.watchRequiredStringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequiredStringArray( forKey: "absentStringEnumArray", as: TestEnum.self, updatesHandler: awaitFirst ) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { - try await config.watchRequiredStringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - updatesHandler: awaitFirst - ) - } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequiredStringArray( forKey: "failure", diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift.gyb index 098b92b..7bcfb11 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderMethodTestsWatch3.swift.gyb @@ -38,41 +38,31 @@ struct ConfigReaderMethodTestsWatch3 { % lower_test_suffix = lower_first(test_suffix) do { // Optional - success - #expect(try await config.watch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) // Optional - failing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) #expect(try await config.watch${suffix}(forKey: "failure", as: ${test_type}.self, updatesHandler: awaitFirst) == .some(nil)) // Defaulted - success - #expect(try await config.watch${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watch${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) #expect(try await config.watch${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(try await config.watch${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) #expect(try await config.watch${suffix}(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}, updatesHandler: awaitFirst) == Defaults.other${test_suffix}) // Required - success - #expect(try await config.watchRequired${suffix}(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) #expect(try await config.watchRequired${suffix}(forKey: "${lower_test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, updatesHandler: awaitFirst) } + let error1 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = await #expect(throws: ConfigError.self) { try await config.watchRequired${suffix}(forKey: "absent${test_suffix}", as: ${test_type}.self, updatesHandler: awaitFirst) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${suffix}(forKey: ConfigKey(["failure"]), as: ${test_type}.self, updatesHandler: awaitFirst) } await #expect(throws: TestProvider.TestError.self) { try await config.watchRequired${suffix}(forKey: "failure", as: ${test_type}.self, updatesHandler: awaitFirst) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderTests.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderTests.swift index 793fc88..44c4806 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderTests.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigReaderTests.swift @@ -38,19 +38,6 @@ struct ConfigReaderTests { #expect(scoped.string(forKey: "user-agent") == "Config/1.0 (Test)") } - @available(Configuration 1.0, *) - @Test func scopingCustomDecoder() throws { - let provider = InMemoryProvider( - name: "test", - values: [ - "http.client.user-agent": "Config/1.0 (Test)" - ] - ) - let top = ConfigReader(provider: provider) - let scoped = top.scoped(to: "http", keyDecoderOverride: .colonSeparated) - #expect(scoped.string(forKey: "client:user-agent") == "Config/1.0 (Test)") - } - @available(Configuration 1.0, *) @Test func context() throws { let provider = InMemoryProvider(values: [ @@ -59,8 +46,8 @@ struct ConfigReaderTests { ]) let config = ConfigReader(provider: provider) #expect(config.double(forKey: "http.client.timeout") == nil) - #expect(config.double(forKey: "http.client.timeout", context: ["upstream": "example1.org"]) == 15.0) - #expect(config.double(forKey: "http.client.timeout", context: ["upstream": "example2.org"]) == 30.0) + #expect(config.double(forKey: ConfigKey("http.client.timeout", context: ["upstream": "example1.org"])) == 15.0) + #expect(config.double(forKey: ConfigKey("http.client.timeout", context: ["upstream": "example2.org"])) == 30.0) } enum TestEnum: String, Equatable { diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift index a2cb8ec..84b5f20 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift @@ -34,516 +34,326 @@ struct ConfigSnapshotReaderMethodTestsGet1 { try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.string(forKey: ConfigKey(["string"])) == Defaults.string) #expect(snapshot.string(forKey: "string") == Defaults.string) // Optional - missing - #expect(snapshot.string(forKey: ConfigKey(["absentString"])) == nil) #expect(snapshot.string(forKey: "absentString") == nil) // Optional - failing - #expect(snapshot.string(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.string(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.string(forKey: ConfigKey(["string"]), default: Defaults.otherString) == Defaults.string) #expect(snapshot.string(forKey: "string", default: Defaults.otherString) == Defaults.string) // Defaulted - missing - #expect( - snapshot.string(forKey: ConfigKey(["absentString"]), default: Defaults.otherString) - == Defaults.otherString - ) #expect(snapshot.string(forKey: "absentString", default: Defaults.otherString) == Defaults.otherString) // Defaulted - failing - #expect( - snapshot.string(forKey: ConfigKey(["failure"]), default: Defaults.otherString) == Defaults.otherString - ) #expect(snapshot.string(forKey: "failure", default: Defaults.otherString) == Defaults.otherString) // Required - success - try #expect(snapshot.requiredString(forKey: ConfigKey(["string"])) == Defaults.string) try #expect(snapshot.requiredString(forKey: "string") == Defaults.string) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredString(forKey: ConfigKey(["absentString"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absentString") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absentString") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentString"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.int(forKey: ConfigKey(["int"])) == Defaults.int) #expect(snapshot.int(forKey: "int") == Defaults.int) // Optional - missing - #expect(snapshot.int(forKey: ConfigKey(["absentInt"])) == nil) #expect(snapshot.int(forKey: "absentInt") == nil) // Optional - failing - #expect(snapshot.int(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.int(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.int(forKey: ConfigKey(["int"]), default: Defaults.otherInt) == Defaults.int) #expect(snapshot.int(forKey: "int", default: Defaults.otherInt) == Defaults.int) // Defaulted - missing - #expect(snapshot.int(forKey: ConfigKey(["absentInt"]), default: Defaults.otherInt) == Defaults.otherInt) #expect(snapshot.int(forKey: "absentInt", default: Defaults.otherInt) == Defaults.otherInt) // Defaulted - failing - #expect(snapshot.int(forKey: ConfigKey(["failure"]), default: Defaults.otherInt) == Defaults.otherInt) #expect(snapshot.int(forKey: "failure", default: Defaults.otherInt) == Defaults.otherInt) // Required - success - try #expect(snapshot.requiredInt(forKey: ConfigKey(["int"])) == Defaults.int) try #expect(snapshot.requiredInt(forKey: "int") == Defaults.int) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredInt(forKey: ConfigKey(["absentInt"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredInt(forKey: "absentInt") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredInt(forKey: "absentInt") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentInt"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredInt(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredInt(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.double(forKey: ConfigKey(["double"])) == Defaults.double) #expect(snapshot.double(forKey: "double") == Defaults.double) // Optional - missing - #expect(snapshot.double(forKey: ConfigKey(["absentDouble"])) == nil) #expect(snapshot.double(forKey: "absentDouble") == nil) // Optional - failing - #expect(snapshot.double(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.double(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.double(forKey: ConfigKey(["double"]), default: Defaults.otherDouble) == Defaults.double) #expect(snapshot.double(forKey: "double", default: Defaults.otherDouble) == Defaults.double) // Defaulted - missing - #expect( - snapshot.double(forKey: ConfigKey(["absentDouble"]), default: Defaults.otherDouble) - == Defaults.otherDouble - ) #expect(snapshot.double(forKey: "absentDouble", default: Defaults.otherDouble) == Defaults.otherDouble) // Defaulted - failing - #expect( - snapshot.double(forKey: ConfigKey(["failure"]), default: Defaults.otherDouble) == Defaults.otherDouble - ) #expect(snapshot.double(forKey: "failure", default: Defaults.otherDouble) == Defaults.otherDouble) // Required - success - try #expect(snapshot.requiredDouble(forKey: ConfigKey(["double"])) == Defaults.double) try #expect(snapshot.requiredDouble(forKey: "double") == Defaults.double) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredDouble(forKey: ConfigKey(["absentDouble"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredDouble(forKey: "absentDouble") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredDouble(forKey: "absentDouble") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDouble"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredDouble(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredDouble(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.bool(forKey: ConfigKey(["bool"])) == Defaults.bool) #expect(snapshot.bool(forKey: "bool") == Defaults.bool) // Optional - missing - #expect(snapshot.bool(forKey: ConfigKey(["absentBool"])) == nil) #expect(snapshot.bool(forKey: "absentBool") == nil) // Optional - failing - #expect(snapshot.bool(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.bool(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.bool(forKey: ConfigKey(["bool"]), default: Defaults.otherBool) == Defaults.bool) #expect(snapshot.bool(forKey: "bool", default: Defaults.otherBool) == Defaults.bool) // Defaulted - missing - #expect(snapshot.bool(forKey: ConfigKey(["absentBool"]), default: Defaults.otherBool) == Defaults.otherBool) #expect(snapshot.bool(forKey: "absentBool", default: Defaults.otherBool) == Defaults.otherBool) // Defaulted - failing - #expect(snapshot.bool(forKey: ConfigKey(["failure"]), default: Defaults.otherBool) == Defaults.otherBool) #expect(snapshot.bool(forKey: "failure", default: Defaults.otherBool) == Defaults.otherBool) // Required - success - try #expect(snapshot.requiredBool(forKey: ConfigKey(["bool"])) == Defaults.bool) try #expect(snapshot.requiredBool(forKey: "bool") == Defaults.bool) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredBool(forKey: ConfigKey(["absentBool"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredBool(forKey: "absentBool") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredBool(forKey: "absentBool") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBool"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredBool(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredBool(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.bytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) #expect(snapshot.bytes(forKey: "bytes") == Defaults.bytes) // Optional - missing - #expect(snapshot.bytes(forKey: ConfigKey(["absentBytes"])) == nil) #expect(snapshot.bytes(forKey: "absentBytes") == nil) // Optional - failing - #expect(snapshot.bytes(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.bytes(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.bytes(forKey: ConfigKey(["bytes"]), default: Defaults.otherBytes) == Defaults.bytes) #expect(snapshot.bytes(forKey: "bytes", default: Defaults.otherBytes) == Defaults.bytes) // Defaulted - missing - #expect( - snapshot.bytes(forKey: ConfigKey(["absentBytes"]), default: Defaults.otherBytes) == Defaults.otherBytes - ) #expect(snapshot.bytes(forKey: "absentBytes", default: Defaults.otherBytes) == Defaults.otherBytes) // Defaulted - failing - #expect(snapshot.bytes(forKey: ConfigKey(["failure"]), default: Defaults.otherBytes) == Defaults.otherBytes) #expect(snapshot.bytes(forKey: "failure", default: Defaults.otherBytes) == Defaults.otherBytes) // Required - success - try #expect(snapshot.requiredBytes(forKey: ConfigKey(["bytes"])) == Defaults.bytes) try #expect(snapshot.requiredBytes(forKey: "bytes") == Defaults.bytes) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredBytes(forKey: ConfigKey(["absentBytes"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredBytes(forKey: "absentBytes") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredBytes(forKey: "absentBytes") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBytes"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredBytes(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredBytes(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.stringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray) #expect(snapshot.stringArray(forKey: "stringArray") == Defaults.stringArray) // Optional - missing - #expect(snapshot.stringArray(forKey: ConfigKey(["absentStringArray"])) == nil) #expect(snapshot.stringArray(forKey: "absentStringArray") == nil) // Optional - failing - #expect(snapshot.stringArray(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.stringArray(forKey: "failure") == nil) // Defaulted - success - #expect( - snapshot.stringArray(forKey: ConfigKey(["stringArray"]), default: Defaults.otherStringArray) - == Defaults.stringArray - ) #expect( snapshot.stringArray(forKey: "stringArray", default: Defaults.otherStringArray) == Defaults.stringArray ) // Defaulted - missing - #expect( - snapshot.stringArray(forKey: ConfigKey(["absentStringArray"]), default: Defaults.otherStringArray) - == Defaults.otherStringArray - ) #expect( snapshot.stringArray(forKey: "absentStringArray", default: Defaults.otherStringArray) == Defaults.otherStringArray ) // Defaulted - failing - #expect( - snapshot.stringArray(forKey: ConfigKey(["failure"]), default: Defaults.otherStringArray) - == Defaults.otherStringArray - ) #expect( snapshot.stringArray(forKey: "failure", default: Defaults.otherStringArray) == Defaults.otherStringArray ) // Required - success - try #expect(snapshot.requiredStringArray(forKey: ConfigKey(["stringArray"])) == Defaults.stringArray) try #expect(snapshot.requiredStringArray(forKey: "stringArray") == Defaults.stringArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredStringArray(forKey: ConfigKey(["absentStringArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: "absentStringArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredStringArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredStringArray(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.intArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) #expect(snapshot.intArray(forKey: "intArray") == Defaults.intArray) // Optional - missing - #expect(snapshot.intArray(forKey: ConfigKey(["absentIntArray"])) == nil) #expect(snapshot.intArray(forKey: "absentIntArray") == nil) // Optional - failing - #expect(snapshot.intArray(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.intArray(forKey: "failure") == nil) // Defaulted - success - #expect( - snapshot.intArray(forKey: ConfigKey(["intArray"]), default: Defaults.otherIntArray) == Defaults.intArray - ) #expect(snapshot.intArray(forKey: "intArray", default: Defaults.otherIntArray) == Defaults.intArray) // Defaulted - missing - #expect( - snapshot.intArray(forKey: ConfigKey(["absentIntArray"]), default: Defaults.otherIntArray) - == Defaults.otherIntArray - ) #expect( snapshot.intArray(forKey: "absentIntArray", default: Defaults.otherIntArray) == Defaults.otherIntArray ) // Defaulted - failing - #expect( - snapshot.intArray(forKey: ConfigKey(["failure"]), default: Defaults.otherIntArray) - == Defaults.otherIntArray - ) #expect(snapshot.intArray(forKey: "failure", default: Defaults.otherIntArray) == Defaults.otherIntArray) // Required - success - try #expect(snapshot.requiredIntArray(forKey: ConfigKey(["intArray"])) == Defaults.intArray) try #expect(snapshot.requiredIntArray(forKey: "intArray") == Defaults.intArray) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredIntArray(forKey: ConfigKey(["absentIntArray"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredIntArray(forKey: "absentIntArray") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredIntArray(forKey: "absentIntArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentIntArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredIntArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredIntArray(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.doubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray) #expect(snapshot.doubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Optional - missing - #expect(snapshot.doubleArray(forKey: ConfigKey(["absentDoubleArray"])) == nil) #expect(snapshot.doubleArray(forKey: "absentDoubleArray") == nil) // Optional - failing - #expect(snapshot.doubleArray(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.doubleArray(forKey: "failure") == nil) // Defaulted - success - #expect( - snapshot.doubleArray(forKey: ConfigKey(["doubleArray"]), default: Defaults.otherDoubleArray) - == Defaults.doubleArray - ) #expect( snapshot.doubleArray(forKey: "doubleArray", default: Defaults.otherDoubleArray) == Defaults.doubleArray ) // Defaulted - missing - #expect( - snapshot.doubleArray(forKey: ConfigKey(["absentDoubleArray"]), default: Defaults.otherDoubleArray) - == Defaults.otherDoubleArray - ) #expect( snapshot.doubleArray(forKey: "absentDoubleArray", default: Defaults.otherDoubleArray) == Defaults.otherDoubleArray ) // Defaulted - failing - #expect( - snapshot.doubleArray(forKey: ConfigKey(["failure"]), default: Defaults.otherDoubleArray) - == Defaults.otherDoubleArray - ) #expect( snapshot.doubleArray(forKey: "failure", default: Defaults.otherDoubleArray) == Defaults.otherDoubleArray ) // Required - success - try #expect(snapshot.requiredDoubleArray(forKey: ConfigKey(["doubleArray"])) == Defaults.doubleArray) try #expect(snapshot.requiredDoubleArray(forKey: "doubleArray") == Defaults.doubleArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredDoubleArray(forKey: ConfigKey(["absentDoubleArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredDoubleArray(forKey: "absentDoubleArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentDoubleArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredDoubleArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredDoubleArray(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.boolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) #expect(snapshot.boolArray(forKey: "boolArray") == Defaults.boolArray) // Optional - missing - #expect(snapshot.boolArray(forKey: ConfigKey(["absentBoolArray"])) == nil) #expect(snapshot.boolArray(forKey: "absentBoolArray") == nil) // Optional - failing - #expect(snapshot.boolArray(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.boolArray(forKey: "failure") == nil) // Defaulted - success - #expect( - snapshot.boolArray(forKey: ConfigKey(["boolArray"]), default: Defaults.otherBoolArray) - == Defaults.boolArray - ) #expect(snapshot.boolArray(forKey: "boolArray", default: Defaults.otherBoolArray) == Defaults.boolArray) // Defaulted - missing - #expect( - snapshot.boolArray(forKey: ConfigKey(["absentBoolArray"]), default: Defaults.otherBoolArray) - == Defaults.otherBoolArray - ) #expect( snapshot.boolArray(forKey: "absentBoolArray", default: Defaults.otherBoolArray) == Defaults.otherBoolArray ) // Defaulted - failing - #expect( - snapshot.boolArray(forKey: ConfigKey(["failure"]), default: Defaults.otherBoolArray) - == Defaults.otherBoolArray - ) #expect(snapshot.boolArray(forKey: "failure", default: Defaults.otherBoolArray) == Defaults.otherBoolArray) // Required - success - try #expect(snapshot.requiredBoolArray(forKey: ConfigKey(["boolArray"])) == Defaults.boolArray) try #expect(snapshot.requiredBoolArray(forKey: "boolArray") == Defaults.boolArray) // Required - missing - let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredBoolArray(forKey: ConfigKey(["absentBoolArray"])) - } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredBoolArray(forKey: "absentBoolArray") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredBoolArray(forKey: "absentBoolArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentBoolArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredBoolArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredBoolArray(forKey: "failure") } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.byteChunkArray(forKey: ConfigKey(["byteChunkArray"])) == Defaults.byteChunkArray) #expect(snapshot.byteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Optional - missing - #expect(snapshot.byteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) == nil) #expect(snapshot.byteChunkArray(forKey: "absentByteChunkArray") == nil) // Optional - failing - #expect(snapshot.byteChunkArray(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.byteChunkArray(forKey: "failure") == nil) // Defaulted - success - #expect( - snapshot.byteChunkArray(forKey: ConfigKey(["byteChunkArray"]), default: Defaults.otherByteChunkArray) - == Defaults.byteChunkArray - ) #expect( snapshot.byteChunkArray(forKey: "byteChunkArray", default: Defaults.otherByteChunkArray) == Defaults.byteChunkArray ) // Defaulted - missing - #expect( - snapshot.byteChunkArray( - forKey: ConfigKey(["absentByteChunkArray"]), - default: Defaults.otherByteChunkArray - ) == Defaults.otherByteChunkArray - ) #expect( snapshot.byteChunkArray(forKey: "absentByteChunkArray", default: Defaults.otherByteChunkArray) == Defaults.otherByteChunkArray ) // Defaulted - failing - #expect( - snapshot.byteChunkArray(forKey: ConfigKey(["failure"]), default: Defaults.otherByteChunkArray) - == Defaults.otherByteChunkArray - ) #expect( snapshot.byteChunkArray(forKey: "failure", default: Defaults.otherByteChunkArray) == Defaults.otherByteChunkArray ) // Required - success - try #expect( - snapshot.requiredByteChunkArray(forKey: ConfigKey(["byteChunkArray"])) == Defaults.byteChunkArray - ) try #expect(snapshot.requiredByteChunkArray(forKey: "byteChunkArray") == Defaults.byteChunkArray) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredByteChunkArray(forKey: ConfigKey(["absentByteChunkArray"])) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredByteChunkArray(forKey: "absentByteChunkArray") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentByteChunkArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredByteChunkArray(forKey: ConfigKey(["failure"])) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredByteChunkArray(forKey: "failure") } } } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift.gyb index f2aa635..6fe0431 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet1.swift.gyb @@ -36,41 +36,31 @@ struct ConfigSnapshotReaderMethodTestsGet1 { % lower_name = lower_first(name) try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.${lower_name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) #expect(snapshot.${lower_name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Optional - missing - #expect(snapshot.${lower_name}(forKey: ConfigKey(["absent${name}"])) == nil) #expect(snapshot.${lower_name}(forKey: "absent${name}") == nil) // Optional - failing - #expect(snapshot.${lower_name}(forKey: ConfigKey(["failure"])) == nil) #expect(snapshot.${lower_name}(forKey: "failure") == nil) // Defaulted - success - #expect(snapshot.${lower_name}(forKey: ConfigKey(["${lower_name}"]), default: Defaults.other${name}) == Defaults.${lower_name}) #expect(snapshot.${lower_name}(forKey: "${lower_name}", default: Defaults.other${name}) == Defaults.${lower_name}) // Defaulted - missing - #expect(snapshot.${lower_name}(forKey: ConfigKey(["absent${name}"]), default: Defaults.other${name}) == Defaults.other${name}) #expect(snapshot.${lower_name}(forKey: "absent${name}", default: Defaults.other${name}) == Defaults.other${name}) // Defaulted - failing - #expect(snapshot.${lower_name}(forKey: ConfigKey(["failure"]), default: Defaults.other${name}) == Defaults.other${name}) #expect(snapshot.${lower_name}(forKey: "failure", default: Defaults.other${name}) == Defaults.other${name}) // Required - success - try #expect(snapshot.required${name}(forKey: ConfigKey(["${lower_name}"])) == Defaults.${lower_name}) try #expect(snapshot.required${name}(forKey: "${lower_name}") == Defaults.${lower_name}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try snapshot.required${name}(forKey: ConfigKey(["absent${name}"])) } + let error1 = #expect(throws: ConfigError.self) { try snapshot.required${name}(forKey: "absent${name}") } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.required${name}(forKey: "absent${name}") } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${name}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.required${name}(forKey: ConfigKey(["failure"])) } #expect(throws: TestProvider.TestError.self) { try snapshot.required${name}(forKey: "failure") } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift index 0bfd04b..a7b7e30 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift @@ -34,33 +34,18 @@ struct ConfigSnapshotReaderMethodTestsGet2 { try config.withSnapshot { snapshot in // Optional - success - #expect( - snapshot.string(forKey: ConfigKey(["stringConvertible"]), as: TestStringConvertible.self) - == Defaults.stringConvertible - ) #expect( snapshot.string(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible ) // Optional - missing - #expect( - snapshot.string(forKey: ConfigKey(["absentStringConvertible"]), as: TestStringConvertible.self) == nil - ) #expect(snapshot.string(forKey: "absentStringConvertible", as: TestStringConvertible.self) == nil) // Optional - failing - #expect(snapshot.string(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) == nil) #expect(snapshot.string(forKey: "failure", as: TestStringConvertible.self) == nil) // Defaulted - success - #expect( - snapshot.string( - forKey: ConfigKey(["stringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.stringConvertible - ) #expect( snapshot.string( forKey: "stringConvertible", @@ -70,13 +55,6 @@ struct ConfigSnapshotReaderMethodTestsGet2 { ) // Defaulted - missing - #expect( - snapshot.string( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.otherStringConvertible - ) #expect( snapshot.string( forKey: "absentStringConvertible", @@ -86,13 +64,6 @@ struct ConfigSnapshotReaderMethodTestsGet2 { ) // Defaulted - failing - #expect( - snapshot.string( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertible - ) == Defaults.otherStringConvertible - ) #expect( snapshot.string( forKey: "failure", @@ -102,10 +73,6 @@ struct ConfigSnapshotReaderMethodTestsGet2 { ) // Required - success - try #expect( - snapshot.requiredString(forKey: ConfigKey(["stringConvertible"]), as: TestStringConvertible.self) - == Defaults.stringConvertible - ) try #expect( snapshot.requiredString(forKey: "stringConvertible", as: TestStringConvertible.self) == Defaults.stringConvertible @@ -113,91 +80,53 @@ struct ConfigSnapshotReaderMethodTestsGet2 { // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredString( - forKey: ConfigKey(["absentStringConvertible"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absentStringConvertible", as: TestStringConvertible.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertible"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredString(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: "failure", as: TestStringConvertible.self) } } try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.string(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) == Defaults.stringEnum) #expect(snapshot.string(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum) // Optional - missing - #expect(snapshot.string(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) == nil) #expect(snapshot.string(forKey: "absentStringEnum", as: TestEnum.self) == nil) // Optional - failing - #expect(snapshot.string(forKey: ConfigKey(["failure"]), as: TestEnum.self) == nil) #expect(snapshot.string(forKey: "failure", as: TestEnum.self) == nil) // Defaulted - success - #expect( - snapshot.string(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self, default: Defaults.otherStringEnum) - == Defaults.stringEnum - ) #expect( snapshot.string(forKey: "stringEnum", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.stringEnum ) // Defaulted - missing - #expect( - snapshot.string( - forKey: ConfigKey(["absentStringEnum"]), - as: TestEnum.self, - default: Defaults.otherStringEnum - ) == Defaults.otherStringEnum - ) #expect( snapshot.string(forKey: "absentStringEnum", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.otherStringEnum ) // Defaulted - failing - #expect( - snapshot.string(forKey: ConfigKey(["failure"]), as: TestEnum.self, default: Defaults.otherStringEnum) - == Defaults.otherStringEnum - ) #expect( snapshot.string(forKey: "failure", as: TestEnum.self, default: Defaults.otherStringEnum) == Defaults.otherStringEnum ) // Required - success - try #expect( - snapshot.requiredString(forKey: ConfigKey(["stringEnum"]), as: TestEnum.self) == Defaults.stringEnum - ) try #expect(snapshot.requiredString(forKey: "stringEnum", as: TestEnum.self) == Defaults.stringEnum) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredString(forKey: ConfigKey(["absentStringEnum"]), as: TestEnum.self) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absentStringEnum", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnum"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredString(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift.gyb index 006c34d..77f5ab5 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet2.swift.gyb @@ -37,41 +37,31 @@ struct ConfigSnapshotReaderMethodTestsGet2 { % lower_test_suffix = lower_first(test_suffix) try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.string(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(snapshot.string(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(snapshot.string(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(snapshot.string(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - #expect(snapshot.string(forKey: ConfigKey(["failure"]), as: ${test_type}.self) == nil) #expect(snapshot.string(forKey: "failure", as: ${test_type}.self) == nil) // Defaulted - success - #expect(snapshot.string(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(snapshot.string(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(snapshot.string(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(snapshot.string(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(snapshot.string(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(snapshot.string(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Required - success - try #expect(snapshot.requiredString(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) try #expect(snapshot.requiredString(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredString(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredString(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift index b0db196..f0d0a87 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift @@ -34,36 +34,18 @@ struct ConfigSnapshotReaderMethodTestsGet3 { try config.withSnapshot { snapshot in // Optional - success - #expect( - snapshot.stringArray(forKey: ConfigKey(["stringConvertibleArray"]), as: TestStringConvertible.self) - == Defaults.stringConvertibleArray - ) #expect( snapshot.stringArray(forKey: "stringConvertibleArray", as: TestStringConvertible.self) == Defaults.stringConvertibleArray ) // Optional - missing - #expect( - snapshot.stringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self - ) == nil - ) #expect(snapshot.stringArray(forKey: "absentStringConvertibleArray", as: TestStringConvertible.self) == nil) // Optional - failing - #expect(snapshot.stringArray(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) == nil) #expect(snapshot.stringArray(forKey: "failure", as: TestStringConvertible.self) == nil) // Defaulted - success - #expect( - snapshot.stringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.stringConvertibleArray - ) #expect( snapshot.stringArray( forKey: "stringConvertibleArray", @@ -73,13 +55,6 @@ struct ConfigSnapshotReaderMethodTestsGet3 { ) // Defaulted - missing - #expect( - snapshot.stringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.otherStringConvertibleArray - ) #expect( snapshot.stringArray( forKey: "absentStringConvertibleArray", @@ -89,13 +64,6 @@ struct ConfigSnapshotReaderMethodTestsGet3 { ) // Defaulted - failing - #expect( - snapshot.stringArray( - forKey: ConfigKey(["failure"]), - as: TestStringConvertible.self, - default: Defaults.otherStringConvertibleArray - ) == Defaults.otherStringConvertibleArray - ) #expect( snapshot.stringArray( forKey: "failure", @@ -105,12 +73,6 @@ struct ConfigSnapshotReaderMethodTestsGet3 { ) // Required - success - try #expect( - snapshot.requiredStringArray( - forKey: ConfigKey(["stringConvertibleArray"]), - as: TestStringConvertible.self - ) == Defaults.stringConvertibleArray - ) try #expect( snapshot.requiredStringArray(forKey: "stringConvertibleArray", as: TestStringConvertible.self) == Defaults.stringConvertibleArray @@ -118,49 +80,26 @@ struct ConfigSnapshotReaderMethodTestsGet3 { // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredStringArray( - forKey: ConfigKey(["absentStringConvertibleArray"]), - as: TestStringConvertible.self - ) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: "absentStringConvertibleArray", as: TestStringConvertible.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringConvertibleArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredStringArray(forKey: ConfigKey(["failure"]), as: TestStringConvertible.self) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredStringArray(forKey: "failure", as: TestStringConvertible.self) } } try config.withSnapshot { snapshot in // Optional - success - #expect( - snapshot.stringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) #expect(snapshot.stringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray) // Optional - missing - #expect(snapshot.stringArray(forKey: ConfigKey(["absentStringEnumArray"]), as: TestEnum.self) == nil) #expect(snapshot.stringArray(forKey: "absentStringEnumArray", as: TestEnum.self) == nil) // Optional - failing - #expect(snapshot.stringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) == nil) #expect(snapshot.stringArray(forKey: "failure", as: TestEnum.self) == nil) // Defaulted - success - #expect( - snapshot.stringArray( - forKey: ConfigKey(["stringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.stringEnumArray - ) #expect( snapshot.stringArray( forKey: "stringEnumArray", @@ -170,13 +109,6 @@ struct ConfigSnapshotReaderMethodTestsGet3 { ) // Defaulted - missing - #expect( - snapshot.stringArray( - forKey: ConfigKey(["absentStringEnumArray"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.otherStringEnumArray - ) #expect( snapshot.stringArray( forKey: "absentStringEnumArray", @@ -186,41 +118,23 @@ struct ConfigSnapshotReaderMethodTestsGet3 { ) // Defaulted - failing - #expect( - snapshot.stringArray( - forKey: ConfigKey(["failure"]), - as: TestEnum.self, - default: Defaults.otherStringEnumArray - ) == Defaults.otherStringEnumArray - ) #expect( snapshot.stringArray(forKey: "failure", as: TestEnum.self, default: Defaults.otherStringEnumArray) == Defaults.otherStringEnumArray ) // Required - success - try #expect( - snapshot.requiredStringArray(forKey: ConfigKey(["stringEnumArray"]), as: TestEnum.self) - == Defaults.stringEnumArray - ) try #expect( snapshot.requiredStringArray(forKey: "stringEnumArray", as: TestEnum.self) == Defaults.stringEnumArray ) // Required - missing let error1 = #expect(throws: ConfigError.self) { - try snapshot.requiredStringArray(forKey: ConfigKey(["absentStringEnumArray"]), as: TestEnum.self) - } - #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: "absentStringEnumArray", as: TestEnum.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) + #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absentStringEnumArray"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { - try snapshot.requiredStringArray(forKey: ConfigKey(["failure"]), as: TestEnum.self) - } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredStringArray(forKey: "failure", as: TestEnum.self) } diff --git a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift.gyb b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift.gyb index 2005661..c5f7a32 100644 --- a/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift.gyb +++ b/Tests/ConfigurationTests/ConfigReaderTests/ConfigSnapshotReaderMethodTestsGet3.swift.gyb @@ -37,41 +37,31 @@ struct ConfigSnapshotReaderMethodTestsGet3 { % lower_test_suffix = lower_first(test_suffix) try config.withSnapshot { snapshot in // Optional - success - #expect(snapshot.stringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) #expect(snapshot.stringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Optional - missing - #expect(snapshot.stringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) == nil) #expect(snapshot.stringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) == nil) // Optional - failing - #expect(snapshot.stringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self) == nil) #expect(snapshot.stringArray(forKey: "failure", as: ${test_type}.self) == nil) // Defaulted - success - #expect(snapshot.stringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) #expect(snapshot.stringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.${lower_test_suffix}) // Defaulted - missing - #expect(snapshot.stringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(snapshot.stringArray(forKey: "absent${test_suffix}", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Defaulted - failing - #expect(snapshot.stringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) #expect(snapshot.stringArray(forKey: "failure", as: ${test_type}.self, default: Defaults.other${test_suffix}) == Defaults.other${test_suffix}) // Required - success - try #expect(snapshot.requiredStringArray(forKey: ConfigKey(["${lower_test_suffix}"]), as: ${test_type}.self) == Defaults.${lower_test_suffix}) try #expect(snapshot.requiredStringArray(forKey: "${lower_test_suffix}", as: ${test_type}.self) == Defaults.${lower_test_suffix}) // Required - missing - let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: ConfigKey(["absent${test_suffix}"]), as: ${test_type}.self) } + let error1 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) } #expect(error1 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) - let error2 = #expect(throws: ConfigError.self) { try snapshot.requiredStringArray(forKey: "absent${test_suffix}", as: ${test_type}.self) } - #expect(error2 == .missingRequiredConfigValue(AbsoluteConfigKey(["absent${test_suffix}"]))) // Required - failing - #expect(throws: TestProvider.TestError.self) { try snapshot.requiredStringArray(forKey: ConfigKey(["failure"]), as: ${test_type}.self) } #expect(throws: TestProvider.TestError.self) { try snapshot.requiredStringArray(forKey: "failure", as: ${test_type}.self) } } % end diff --git a/Tests/ConfigurationTests/ConfigSnapshotReaderTests.swift b/Tests/ConfigurationTests/ConfigSnapshotReaderTests.swift index e4e30c8..720966a 100644 --- a/Tests/ConfigurationTests/ConfigSnapshotReaderTests.swift +++ b/Tests/ConfigurationTests/ConfigSnapshotReaderTests.swift @@ -66,19 +66,4 @@ struct ConfigSnapshotReaderTests { #expect(scoped.string(forKey: "user-agent") == "Config/1.0 (Test)") } } - - @available(Configuration 1.0, *) - @Test func scopingCustomDecoder() throws { - let provider = InMemoryProvider( - name: "test", - values: [ - "http.client.user-agent": "Config/1.0 (Test)" - ] - ) - let config = ConfigReader(provider: provider) - config.withSnapshot { snapshot in - let scoped = snapshot.scoped(to: "http", keyDecoderOverride: .colonSeparated) - #expect(scoped.string(forKey: "client:user-agent") == "Config/1.0 (Test)") - } - } }