From d062fdaba2328d073011edbf5f1ab22d1e0942d6 Mon Sep 17 00:00:00 2001 From: Paul Kraft Date: Tue, 4 May 2021 16:15:26 +0200 Subject: [PATCH] Introduce Publish resultBuilder --- Sources/XUI/Combine/CancellableBuilder.swift | 2 +- Sources/XUI/Combine/Publish.swift | 80 ++++++++++++++++++++ Sources/XUI/Combine/PublishModifier.swift | 33 ++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 Sources/XUI/Combine/Publish.swift create mode 100644 Sources/XUI/Combine/PublishModifier.swift diff --git a/Sources/XUI/Combine/CancellableBuilder.swift b/Sources/XUI/Combine/CancellableBuilder.swift index e23a310..eba5cd9 100644 --- a/Sources/XUI/Combine/CancellableBuilder.swift +++ b/Sources/XUI/Combine/CancellableBuilder.swift @@ -11,7 +11,7 @@ /// /// Possible use case: Storing multiple cancellables in a collection /// without writing `.store(in:)` for each subscription separately. -@_functionBuilder +@resultBuilder public struct CancellableBuilder { public static func buildBlock(_ components: [Cancellable]...) -> [Cancellable] { diff --git a/Sources/XUI/Combine/Publish.swift b/Sources/XUI/Combine/Publish.swift new file mode 100644 index 0000000..3a7ec56 --- /dev/null +++ b/Sources/XUI/Combine/Publish.swift @@ -0,0 +1,80 @@ +// +// File.swift +// +// +// Created by Paul Kraft on 04.05.21. +// + +public typealias Pipeline = AnyPublisher +public typealias Observable = AnyPublisher + +@resultBuilder +public struct Publish { + + // MARK: Build + + public static func build( + @Publish from build: () -> P + ) -> P { + build() + } + + public static func build( + @Publish from build: () throws -> AnyPublisher + ) -> AnyPublisher { + do { + return try build() + } catch { + return Modifier.modify(Fail(error: error)) + } + } + + // MARK: Build Block + + public static func buildBlock( + _ component: Output + ) -> AnyPublisher { + Modifier.modify(Just(component)) + } + + public static func buildBlock( + _ component: Output + ) -> AnyPublisher { + Modifier.modify(Just(component).setFailureType(to: Error.self)) + } + + public static func buildBlock( + _ component: P + ) -> AnyPublisher where P.Failure == Never { + Modifier.modify(component) + } + + public static func buildBlock( + _ component: P + ) -> AnyPublisher where P.Failure == Never { + Modifier.modify(component.setFailureType(to: Error.self)) + } + + public static func buildBlock( + _ component: P + ) -> AnyPublisher { + Modifier.modify(component.mapError { $0 as Error }) + } + + // MARK: Build Either + + public static func buildEither(first component: P) -> P { + component + } + + public static func buildEither(second component: P) -> P { + component + } + + // MARK: Build Limited Availability + + public static func buildLimitedAvailability(_ component: P) -> P { + component + } + +} diff --git a/Sources/XUI/Combine/PublishModifier.swift b/Sources/XUI/Combine/PublishModifier.swift new file mode 100644 index 0000000..222f71c --- /dev/null +++ b/Sources/XUI/Combine/PublishModifier.swift @@ -0,0 +1,33 @@ +// +// File.swift +// +// +// Created by Paul Kraft on 04.05.21. +// + +public protocol PublishModifier { + static func modify(_ publisher: P) -> AnyPublisher +} + +public struct MainQueue: PublishModifier { + + public static func modify( + _ publisher: P + ) -> AnyPublisher { + publisher + .receive(on: DispatchQueue.main) + .eraseToAnyPublisher() + } + +} + +extension Never: PublishModifier { + + public static func modify( + _ publisher: P + ) -> AnyPublisher { + publisher + .eraseToAnyPublisher() + } + +}