cleanup Theme
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
import Foundation
|
||||||
|
import TOML
|
||||||
|
|
||||||
|
extension PHTheme {
|
||||||
|
/// Load theme from the config directory (~/.config/phbar/themes/).
|
||||||
|
/// If the file doesn't exist or fails to parse, defaults are used (non-fatal).
|
||||||
|
static func load(_ theme: String?) throws -> PHTheme {
|
||||||
|
guard let theme else { return try loadFromBundle() }
|
||||||
|
|
||||||
|
let url = FileManager.default.homeDirectoryForCurrentUser.appending(
|
||||||
|
path: ".config/phbar/themes/\(theme).toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
if FileManager.default.fileExists(atPath: url.relativePath) {
|
||||||
|
return try load(from: url)
|
||||||
|
} else {
|
||||||
|
return try loadFromBundle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load the bundled theme.
|
||||||
|
/// If the file doesn't exist or fails to parse, the execution is interrupted.
|
||||||
|
static private func loadFromBundle() throws -> PHTheme {
|
||||||
|
guard
|
||||||
|
let defaultConfig = Bundle.module.url(
|
||||||
|
forResource: "theme",
|
||||||
|
withExtension: "toml"
|
||||||
|
)?.resolvingSymlinksInPath()
|
||||||
|
else {
|
||||||
|
throw phbar.Error("Failed to load theme file")
|
||||||
|
}
|
||||||
|
return try load(from: defaultConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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) throws -> PHTheme {
|
||||||
|
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 theme file", underlyingError: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load theme from a TOML string.
|
||||||
|
/// If the content fails to parse, the execution is interrupted.
|
||||||
|
static private func load(from contents: String) throws -> PHTheme {
|
||||||
|
do {
|
||||||
|
let decoder = TOMLDecoder()
|
||||||
|
return try decoder.decode(PHTheme.self, from: contents)
|
||||||
|
} catch {
|
||||||
|
throw phbar.Error("Failed to parse theme file", underlyingError: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,71 +1,9 @@
|
|||||||
import Foundation
|
|
||||||
import TOML
|
|
||||||
|
|
||||||
struct PHTheme: Decodable {
|
struct PHTheme: Decodable {
|
||||||
let window: PHThemeWindow
|
let window: PHThemeWindow
|
||||||
let styles: [PHThemeStyle]
|
let styles: [PHThemeStyle]
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case window
|
case window
|
||||||
case styles = "style"
|
case styles = "style"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loading
|
|
||||||
|
|
||||||
extension PHTheme {
|
|
||||||
/// Load theme from the config directory (~/.config/phbar/themes/).
|
|
||||||
/// If the file doesn't exist or fails to parse, defaults are used (non-fatal).
|
|
||||||
static func load(_ theme: String?) throws -> PHTheme {
|
|
||||||
guard let theme else { return try loadFromBundle() }
|
|
||||||
|
|
||||||
let url = FileManager.default.homeDirectoryForCurrentUser.appending(
|
|
||||||
path: ".config/phbar/themes/\(theme).toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
if FileManager.default.fileExists(atPath: url.relativePath) {
|
|
||||||
return try load(from: url)
|
|
||||||
} else {
|
|
||||||
return try loadFromBundle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load the bundled theme.
|
|
||||||
/// If the file doesn't exist or fails to parse, the execution is interrupted.
|
|
||||||
static private func loadFromBundle() throws -> PHTheme {
|
|
||||||
guard
|
|
||||||
let defaultConfig = Bundle.module.url(
|
|
||||||
forResource: "theme",
|
|
||||||
withExtension: "toml"
|
|
||||||
)?.resolvingSymlinksInPath()
|
|
||||||
else {
|
|
||||||
throw phbar.Error("Failed to load theme file")
|
|
||||||
}
|
|
||||||
return try load(from: defaultConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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) throws -> PHTheme {
|
|
||||||
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 theme file", underlyingError: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load theme from a TOML string.
|
|
||||||
/// If the content fails to parse, the execution is interrupted.
|
|
||||||
static private func load(from contents: String) throws -> PHTheme {
|
|
||||||
do {
|
|
||||||
let decoder = TOMLDecoder()
|
|
||||||
return try decoder.decode(PHTheme.self, from: contents)
|
|
||||||
} catch {
|
|
||||||
throw phbar.Error("Failed to parse theme file", underlyingError: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ struct PHThemeWindow: Decodable {
|
|||||||
let hasShadow: Bool
|
let hasShadow: Bool
|
||||||
let blur: Double
|
let blur: Double
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case hasShadow = "shadow"
|
case hasShadow = "shadow"
|
||||||
case blur
|
case blur
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user