This repository has been archived on 2026-02-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
swift-duct-calc/Sources/Styleguide/ResultView.swift

90 lines
2.0 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: 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)"
}
}
}
}