Files
phbar/Sources/phbar/Models/PHTheme/PHTheme+Loading.swift
T

53 lines
1.9 KiB
Swift

import Foundation
import TOML
extension PHTheme {
/// Load theme from the resolved config directory (`PHPaths`/themes).
/// If the file doesn't exist or fails to parse, the execution is interrupted.
///
/// - Parameter environment: Used to expand `$VAR` references in `@EnvExpanded`
/// fields (colors, fonts); defaults to the process environment.
static func load(_ theme: String, environment: PHEnvironment = .process) throws -> PHTheme {
let url = PHPaths.configDirectory.appending(path: "themes").appending(path: "\(theme).toml")
if FileManager.default.fileExists(atPath: url.relativePath) {
return try load(from: url, environment: environment)
} else {
throw PHBar.Error(
"""
Theme file not found.
Make sure to have a file named `\(theme).toml` inside the
directory: `\(url.deletingLastPathComponent().relativePath)`
Tip: If you've never used phbar before, run the `phbar install` command
to automatically generate the required configuration files.
"""
)
}
}
/// Load theme from a file at URL.
/// If the file doesn't exist or fails to parse, the execution is interrupted.
static private func load(from url: URL, environment: PHEnvironment) throws -> PHTheme {
guard let data = try? Data(contentsOf: url),
let contents = String(data: data, encoding: .utf8), !contents.isEmpty
else {
throw PHBar.Error("Theme file not readable or empty.")
}
return try load(from: contents, environment: environment)
}
/// Load theme from a TOML string.
/// If the content fails to parse, the execution is interrupted.
static private func load(from contents: String, environment: PHEnvironment) throws -> PHTheme {
do {
let decoder = TOMLDecoder()
decoder.userInfo[PHEnvironment.userInfoKey] = environment
return try decoder.decode(PHTheme.self, from: contents)
} catch {
throw PHBar.Error("Theme file not valid", underlyingError: error)
}
}
}