Add require interface, update docs

This commit is contained in:
Alexandr Goncharov 2020-06-10 14:28:51 +03:00 committed by Gitea
parent a7b49b69e6
commit 29e1d34db9
5 changed files with 42 additions and 4 deletions

View File

@ -1,4 +1,4 @@
# Conf
[![Build Status](http://ci.merlin.local/api/badges/adan/Conf/status.svg)](http://ci.merlin.local/adan/Conf)
[![Swift 5](https://img.shields.io/badge/Swift-5-orange.svg?style=flat)](https://developer.apple.com/swift/)
Config made easy

View File

@ -1,17 +1,22 @@
/// Key-value storage that can be filled from multiple sources
/// Key-value storage that can be filled from multiple sources
public final class Config {
/// Returns new config
/// - Parameter useEnvironment: if `true` fallback to the environment values for missing keys
public init(useEnvironment: Bool = false) {
isBackedByEnvironment = useEnvironment
}
/// if `true` fallback to the environment values for missing keys
let isBackedByEnvironment: Bool
private let environment = Environment()
private var data = [Key: String]()
/// Returns value associated with the given `key`
func value(for key: Key) -> String? {
return data[key] ?? envValue(for: key)
}
/// Asks enviroment about value associated with the given `key`
func envValue(for key: Key) -> String? {
guard isBackedByEnvironment,
key.path.count == 1,
@ -20,24 +25,47 @@ public final class Config {
return environment[variable]
}
/// Updates `value` for the given `key`
func set(value: String?, for key: Key) {
data[key] = value
}
/// Returns value associated with the given `key`
public subscript(_ key: Key) -> String? {
get { value(for: key) }
set { set(value: newValue, for: key) }
}
/// Returns value associated with the given `key`
public subscript<Value>(_ key: Key) -> Value? where Value: LosslessStringConvertible {
get { value(for: key).flatMap(Value.init) }
set { set(value: newValue?.description, for: key) }
}
/// Returns value associated with the given `key` or throws an error
/// - Throws: `ConfigurationError.missing`
public func require(_ key: Key) throws -> String {
guard let value = self[key]
else { throw ConfigurationError.missing(key: key) }
return value
}
/// Returns value associated with the given `key` or throws an error
/// - Throws: `ConfigurationError.missing`
public func require<Value>(_ key: Key) throws -> Value where Value: LosslessStringConvertible {
guard let value = self[key] as Value?
else { throw ConfigurationError.missing(key: key) }
return value
}
/// Returns all stored values
public func dump() -> [Key: String] {
data
}
/// Loads values from the given source
/// - Parameter provider: provide values
/// - Throws: `ConfigurationError`
public func load(from provider: ConfigurationProvider) throws {
try data.merge(provider.configuration(),
uniquingKeysWith: { _, new in new })

View File

@ -1,5 +1,11 @@
/// Possible module errors
public enum ConfigurationError: Error {
/// Error during raw data fetching
case fetch(Error)
/// Error during parsing raw data to the specified fortmat
case parse(Error)
/// Error during transforming data to the internal format
case decode(path: Key, value: Any)
/// Missing key requested
case missing(key: Key)
}

View File

@ -1,6 +1,11 @@
import Foundation
/// Configuration values provider
///
/// Incapsulates configuration values fetching from any source
public protocol ConfigurationProvider {
/// Fetches configuration values
///
/// Must throw `ConfigurationError` on error
func configuration() throws -> [Key: String]
}

View File

@ -12,7 +12,6 @@ extension Fetcher {
static let file: (String) -> DefaultConfigurationProvider.Fetcher = { configName in
return {
let url = URL(fileURLWithPath: configName, isDirectory: false)
print(url)
return try Data(contentsOf: url)
}
}