103 lines
2.3 KiB
Swift
103 lines
2.3 KiB
Swift
import Elementary
|
|
import Foundation
|
|
|
|
public struct ResultView<
|
|
V: Sendable,
|
|
E: Error,
|
|
ValueView: HTML,
|
|
ErrorView: HTML
|
|
>: HTML {
|
|
|
|
let onSuccess: @Sendable (V) -> ValueView
|
|
let onError: @Sendable (E) -> ErrorView
|
|
let result: Result<V, E>
|
|
|
|
public init(
|
|
result: Result<V, E>,
|
|
@HTMLBuilder onSuccess: @escaping @Sendable (V) -> ValueView,
|
|
@HTMLBuilder onError: @escaping @Sendable (E) -> ErrorView
|
|
) {
|
|
self.result = result
|
|
self.onError = onError
|
|
self.onSuccess = onSuccess
|
|
}
|
|
|
|
public var body: some HTML {
|
|
switch result {
|
|
case .success(let value):
|
|
onSuccess(value)
|
|
case .failure(let error):
|
|
onError(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ResultView {
|
|
|
|
public init(
|
|
result: Result<V, E>,
|
|
@HTMLBuilder onSuccess: @escaping @Sendable (V) -> ValueView
|
|
) where ErrorView == Styleguide.ErrorView<E> {
|
|
self.init(result: result, onSuccess: onSuccess) { error in
|
|
Styleguide.ErrorView(error: error)
|
|
}
|
|
}
|
|
|
|
public init(
|
|
catching: @escaping @Sendable () async throws(E) -> V,
|
|
@HTMLBuilder onSuccess: @escaping @Sendable (V) -> ValueView
|
|
) async where ErrorView == Styleguide.ErrorView<E> {
|
|
await self.init(
|
|
result: .init(catching: catching),
|
|
onSuccess: onSuccess
|
|
) { error in
|
|
Styleguide.ErrorView(error: error)
|
|
}
|
|
}
|
|
|
|
public init(
|
|
catching: @escaping @Sendable () async throws(E) -> V,
|
|
) async where ErrorView == Styleguide.ErrorView<E>, V == Void, ValueView == EmptyHTML {
|
|
await self.init(
|
|
result: .init(catching: catching),
|
|
onSuccess: { EmptyHTML() }
|
|
) { error in
|
|
Styleguide.ErrorView(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ResultView where V == ValueView {
|
|
|
|
public init(
|
|
catching: @escaping @Sendable () async throws(E) -> V
|
|
) async where ErrorView == Styleguide.ErrorView<E> {
|
|
await self.init(result: .init(catching: catching)) {
|
|
$0
|
|
} onError: { error in
|
|
Styleguide.ErrorView(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ResultView: Sendable where Error: Sendable, ValueView: Sendable, ErrorView: Sendable {}
|
|
|
|
public struct ErrorView<E: Error>: HTML, Sendable where Error: Sendable {
|
|
|
|
let error: E
|
|
|
|
public init(error: E) {
|
|
self.error = error
|
|
}
|
|
|
|
public var body: some HTML<HTMLTag.div> {
|
|
div {
|
|
h1(.class("text-2xl font-bold text-error")) { "Oops: Error" }
|
|
p {
|
|
"\(error)"
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|