Type-safe access to your environment leveraging Swift's Decodable
Add .package(url: "https://github.com/SwiftScream/swift-environment-decoder.git", from: "0.4.0")
to your Package.swift dependencies
import EnvironmentDecoder
struct MyEnvironmentFeatureFlags: Decodable {
let enableA: Bool
let enableB: Bool
}
struct MyEnvironment: Decodable {
let port: UInt16
let allowedRegions: [String]
let featureFlags: MyEnvironmentFeatureFlags
}
let environment = try EnvironmentDecoder().decode(MyEnvironment.self)
print("\(environment.allowedRegions.count) allowed region(s)")
print("listening on port \(environment.port)")
if environment.featureFlags.enableA {
print("A is enabled")
}
if environment.featureFlags.enableB {
print("B is enabled")
}
The above code expects an environment of the form:
PORT=1234
ALLOWED_REGIONS=regionA,regionB,regionC
FEATURE_FLAGS_ENABLE_A=true
FEATURE_FLAGS_ENABLE_B=false
If the environment cannot be decoded into the specified type, a Swift.DecodingError
is thrown.
This is a great way to catch issues with the environment early. In some cases it may be appropriate to output a message, and terminate the process.
Some examples of why this may occur:
- a required environment variable is not specified
- the value of an environment variable cannot be decoded as the specified type
let environment: MyEnvironment
do {
environment = try EnvironmentDecoder().decode(MyEnvironment.self)
} catch {
fatalError(error.localizedDescription)
}
By default EnvironmentDecoder will decode ProcessInfo.processInfo.environment
.
If that's not what you want, you can pass in a [String: String]
instead.
let someEnvDictionary: [String: String] = //...
let environment = try EnvironmentDecoder().decode(MyEnvironment.self, from: someEnvDictionary)