53 lines
1.7 KiB
Swift
53 lines
1.7 KiB
Swift
import Foundation
|
|
import TOML
|
|
|
|
extension PHBlock {
|
|
private struct Wrapper: Decodable {
|
|
let blocks: [PHBlock]
|
|
|
|
private enum CodingKeys: String, CodingKey {
|
|
case blocks = "block"
|
|
}
|
|
}
|
|
|
|
/// Load a named block set from `<configDirectory>/blocks/<name>.toml`.
|
|
///
|
|
/// - Parameter configDirectory: Override the lookup root (used by tests);
|
|
/// defaults to the resolved config directory (see `PHPaths`).
|
|
static func load(_ blocks: String, in configDirectory: URL? = nil) throws -> [PHBlock] {
|
|
let base = configDirectory ?? PHPaths.configDirectory
|
|
|
|
let setFile = base.appending(path: "blocks").appending(path: "\(blocks).toml")
|
|
guard FileManager.default.fileExists(atPath: setFile.relativePath) else {
|
|
throw PHBar.Error("Failed to load blocks '\(blocks)'")
|
|
}
|
|
return try load(from: setFile)
|
|
}
|
|
|
|
/// Load theme from a file at URL.
|
|
/// If the file doesn't exist or fails to parse, the execution is interrupted.
|
|
static func load(from url: URL) throws -> [PHBlock] {
|
|
do {
|
|
let data = try Data(contentsOf: url)
|
|
guard let contents = String(data: data, encoding: .utf8), !contents.isEmpty else {
|
|
throw PHBar.Error("the file is empty")
|
|
}
|
|
return try load(from: contents)
|
|
} catch {
|
|
throw PHBar.Error("Failed to load blocks file", underlyingError: error)
|
|
}
|
|
}
|
|
|
|
/// Load theme from a TOML string.
|
|
/// If the content fails to parse, the execution is interrupted.
|
|
static func load(from contents: String) throws -> [PHBlock] {
|
|
do {
|
|
let decoder = TOMLDecoder()
|
|
let wrapper = try decoder.decode(PHBlock.Wrapper.self, from: contents)
|
|
return wrapper.blocks
|
|
} catch {
|
|
throw PHBar.Error("Failed to parse blocks file", underlyingError: error)
|
|
}
|
|
}
|
|
}
|