Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Sources/Configuration/Documentation.docc/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,6 @@ Any package can implement a ``ConfigProvider``, making the ecosystem extensible
- ``ConfigKey``
- ``AbsoluteConfigKey``
- ``ConfigContextValue``
- ``ConfigKeyEncoder``
- ``SeparatorKeyEncoder``
- ``DirectoryFileKeyEncoder``

### Troubleshooting and access reporting
- <doc:Troubleshooting>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

### Creating a directory files provider

- ``init(directoryPath:allowMissing:secretsSpecifier:arraySeparator:keyEncoder:)``
- ``init(directoryPath:allowMissing:secretsSpecifier:arraySeparator:)``

This file was deleted.

2 changes: 1 addition & 1 deletion Sources/Configuration/KeyCoders/ConfigKeyEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
///
/// - ``AbsoluteConfigKey`` - The structured key representation
@available(Configuration 1.0, *)
public protocol ConfigKeyEncoder: Sendable {
internal protocol ConfigKeyEncoder: Sendable {

/// Encodes a structured configuration key into its string representation.
///
Expand Down
24 changes: 5 additions & 19 deletions Sources/Configuration/KeyCoders/SeparatorKeyEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,20 @@
/// let dashEncoder = ConfigKeyEncoder.dashSeparated
/// ```
@available(Configuration 1.0, *)
public struct SeparatorKeyEncoder {
internal struct SeparatorKeyEncoder {

/// The string used to join key components.
///
/// This separator is inserted between each component when encoding hierarchical
/// keys into flat strings. Common separators include "." for dot notation and
/// "-" for dash notation.
public var separator: String

/// Creates a new separator-based key encoder.
///
/// ```swift
/// let encoder = SeparatorKeyEncoder(separator: "_")
/// let key = AbsoluteConfigKey(components: ["app", "config", "debug"], context: context)
/// let encoded = encoder.encode(key)
/// // Results in "app_config_debug"
/// ```
///
/// - Parameter separator: The string to use for joining key components.
public init(separator: String) {
self.separator = separator
}
var separator: String
}

@available(Configuration 1.0, *)
extension SeparatorKeyEncoder: ConfigKeyEncoder {
// swift-format-ignore: AllPublicDeclarationsHaveDocumentation
public func encode(_ key: AbsoluteConfigKey) -> String {
func encode(_ key: AbsoluteConfigKey) -> String {
key.components.joined(separator: separator)
}
}
Expand All @@ -82,7 +68,7 @@ extension ConfigKeyEncoder where Self == SeparatorKeyEncoder {
/// let encoded = encoder.encode(key)
/// // Results in "app.database.host"
/// ```
public static var dotSeparated: Self {
static var dotSeparated: Self {
SeparatorKeyEncoder(separator: ".")
}

Expand All @@ -97,7 +83,7 @@ extension ConfigKeyEncoder where Self == SeparatorKeyEncoder {
/// let encoded = encoder.encode(key)
/// // Results in "app-database-host"
/// ```
public static var dashSeparated: Self {
static var dashSeparated: Self {
SeparatorKeyEncoder(separator: "-")
}
}
49 changes: 11 additions & 38 deletions Sources/Configuration/Providers/Files/DirectoryFilesProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,13 @@ public import SystemPackage
///
/// ## Key mapping
///
/// By default, configuration keys are transformed into file names using these rules:
/// - Components are joined with dashes
/// - Non-alphanumeric characters (except dashes) are replaced with underscores
/// Configuration keys are transformed into file names using these rules:
/// - Components are joined with dashes.
/// - Non-alphanumeric characters (except dashes) are replaced with underscores.
///
/// For example:
/// - `database.password` -> `database-password`
///
/// You can customize this key mapping by providing a custom `ConfigKeyEncoder` implementation
/// to the initializer.
///
/// ## Value handling
///
/// The provider reads file contents as UTF-8 strings and converts them to the requested
Expand Down Expand Up @@ -103,24 +100,6 @@ public import SystemPackage
/// // ["host1.example.com", "host2.example.com", "host3.example.com"]
/// ```
///
/// ### Custom key encoding
///
/// ```swift
/// // Custom key encoder that uses underscores instead of dashes
/// struct CustomKeyEncoder: ConfigKeyEncoder {
/// func encode(_ key: AbsoluteConfigKey) -> String {
/// key.components.joined(separator: "_")
/// }
/// }
///
/// let provider = try await DirectoryFilesProvider(
/// directoryPath: "/etc/config",
/// keyEncoder: CustomKeyEncoder()
/// )
///
/// // Now "database.password" maps to file "database_password" instead of "database-password"
/// ```
///
/// ## Configuration context
///
/// This provider ignores the context passed in ``AbsoluteConfigKey/context``.
Expand Down Expand Up @@ -152,7 +131,7 @@ public struct DirectoryFilesProvider: Sendable {
var arrayDecoder: DirectoryFilesValueArrayDecoder

/// The key encoder for converting config keys to file names.
var keyEncoder: any ConfigKeyEncoder
var keyEncoder: any ConfigKeyEncoder = .directoryFiles
}

/// The underlying snapshot of the provider.
Expand All @@ -178,22 +157,19 @@ public struct DirectoryFilesProvider: Sendable {
/// - When `true`, if the directory is missing, treats it as empty.
/// - secretsSpecifier: Specifies which values should be treated as secrets.
/// - arraySeparator: The character used to separate elements in array values.
/// - keyEncoder: The encoder to use for converting configuration keys to file names.
/// - Throws: If the directory cannot be found or read.
public init(
directoryPath: FilePath,
allowMissing: Bool = false,
secretsSpecifier: SecretsSpecifier<String, Data> = .all,
arraySeparator: Character = ",",
keyEncoder: some ConfigKeyEncoder = .directoryFiles
arraySeparator: Character = ","
) async throws {
try await self.init(
directoryPath: directoryPath,
allowMissing: allowMissing,
fileSystem: LocalCommonProviderFileSystem(),
secretsSpecifier: secretsSpecifier,
arraySeparator: arraySeparator,
keyEncoder: keyEncoder
arraySeparator: arraySeparator
)
}

Expand All @@ -210,15 +186,13 @@ public struct DirectoryFilesProvider: Sendable {
/// - fileSystem: The file system implementation to use.
/// - secretsSpecifier: Specifies which values should be treated as secrets. Defaults to `.all`.
/// - arraySeparator: The character used to separate elements in array values. Defaults to comma.
/// - keyEncoder: The encoder to use for converting configuration keys to file names.
/// - Throws: If the directory cannot be found or read.
internal init(
directoryPath: FilePath,
allowMissing: Bool,
fileSystem: some CommonProviderFileSystem,
secretsSpecifier: SecretsSpecifier<String, Data> = .all,
arraySeparator: Character = ",",
keyEncoder: some ConfigKeyEncoder = .directoryFiles
arraySeparator: Character = ","
) async throws {
let fileValues = try await Self.loadDirectory(
at: directoryPath,
Expand All @@ -228,8 +202,7 @@ public struct DirectoryFilesProvider: Sendable {
)
self._snapshot = .init(
fileValues: fileValues,
arrayDecoder: DirectoryFilesValueArrayDecoder(separator: arraySeparator),
keyEncoder: keyEncoder
arrayDecoder: DirectoryFilesValueArrayDecoder(separator: arraySeparator)
)
}

Expand Down Expand Up @@ -478,15 +451,15 @@ extension DirectoryFilesProvider: ConfigProvider {
/// - Components are joined with dashes
/// - Non-alphanumeric characters (except dashes) are replaced with underscores
@available(Configuration 1.0, *)
public struct DirectoryFileKeyEncoder {
internal struct DirectoryFileKeyEncoder {
/// Creates a default directory key encoder that follows standard file naming conventions.
public init() {}
}

@available(Configuration 1.0, *)
extension DirectoryFileKeyEncoder: ConfigKeyEncoder {
// swift-format-ignore: AllPublicDeclarationsHaveDocumentation
public func encode(_ key: AbsoluteConfigKey) -> String {
func encode(_ key: AbsoluteConfigKey) -> String {
key.components
.map { component in
component
Expand All @@ -513,7 +486,7 @@ extension ConfigKeyEncoder where Self == DirectoryFileKeyEncoder {
/// - Non-alphanumeric characters (except dashes) are replaced with underscores
///
/// - Returns: A new key encoder.
public static var directoryFiles: Self {
static var directoryFiles: Self {
DirectoryFileKeyEncoder()
}
}
2 changes: 1 addition & 1 deletion Tests/ConfigurationTests/SeparatorKeyEncoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//

import Configuration
@testable import Configuration
import Testing

struct SeparatorKeyEncoderTests {
Expand Down
Loading