Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(CombineBridge): Draft implementation #218

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ let package = Package(
],
swiftSettings: [.define("WASI", .when(platforms: [.wasi]))]
),
.target(name: "OpenCombineBridge", dependencies: ["OpenCombine"]),
.target(name: "OpenCombineDispatch", dependencies: ["OpenCombine"]),
.target(
name: "OpenCombineFoundation",
Expand Down
37 changes: 37 additions & 0 deletions Sources/OpenCombineBridge/Cancellable+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private struct CancellableAdapter: OpenCombine.Cancellable, Combine.Cancellable {
public init(_ cancellable: OpenCombine.Cancellable) {
self._cancel = cancellable.cancel
}

public init(_ cancellable: Combine.Cancellable) {
self._cancel = cancellable.cancel
}

private init(cancel: @escaping () -> Void) {
self._cancel = cancel
}

private let _cancel: () -> Void

func cancel() { _cancel() }
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension OpenCombine.Cancellable {
public var combine: OpenCombine.Cancellable {
CancellableAdapter(self)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Combine.Cancellable {
public var ocombine: OpenCombine.Cancellable {
CancellableAdapter(self)
}
}
#endif
67 changes: 67 additions & 0 deletions Sources/OpenCombineBridge/CombineIdentifier+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private func _rawValue(for id: Combine.CombineIdentifier) -> UInt64 {
Mirror(reflecting: id).children.first(where: { $0.label == "rawValue" })!.value as! UInt64
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private func _rawValue(for id: OpenCombine.CombineIdentifier) -> UInt64 {
Mirror(reflecting: id).children.first(where: { $0.label == "rawValue" })!.value as! UInt64
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private struct _CombineIdentifierProxy {
init(_ object: OpenCombine.CustomCombineIdentifierConvertible) {
self.init(object.combineIdentifier)
}

init(_ object: Combine.CustomCombineIdentifierConvertible) {
self.init(object.combineIdentifier)
}

init(_ combineIdentifier: OpenCombine.CombineIdentifier) {
self.init(rawValue: _rawValue(for: combineIdentifier))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 🚫 Lines should not have trailing whitespace. (trailing_whitespace)

init(_ combineIdentifier: Combine.CombineIdentifier) {
self.init(rawValue: _rawValue(for: combineIdentifier))
}

init(rawValue: UInt64) {
self.rawValue = rawValue
}

var rawValue: UInt64

var combine: Combine.CombineIdentifier {
return copyValue(
of: self,
as: Combine.CombineIdentifier()
)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 🚫 Lines should not have trailing whitespace. (trailing_whitespace)

var ocombine: OpenCombine.CombineIdentifier {
return copyValue(
of: self,
as: OpenCombine.CombineIdentifier()
)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension OpenCombine.CombineIdentifier {
public var combine: Combine.CombineIdentifier {
_CombineIdentifierProxy(self).combine
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Combine.CombineIdentifier {
public var ocombine: OpenCombine.CombineIdentifier {
_CombineIdentifierProxy(self).ocombine
}
}
#endif
9 changes: 9 additions & 0 deletions Sources/OpenCombineBridge/Helpers/CopyValue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

func copyValue<Source, Destination>(of source: Source, as destination: Destination) -> Destination {
var value = source
var buffer = destination
let data = Data(bytes: &value, count: MemoryLayout<Source>.size)
_ = withUnsafeMutableBytes(of: &buffer, { data.copyBytes(to: $0) })
return buffer
}
35 changes: 35 additions & 0 deletions Sources/OpenCombineBridge/Publisher+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct PublisherAdapter<Publisher> {
internal init(_ publisher: Publisher) {
self.publisher = publisher
}

let publisher: Publisher
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension PublisherAdapter: Combine.Publisher where Publisher: OpenCombine.Publisher {
public typealias Output = Publisher.Output
public typealias Failure = Publisher.Failure

public func receive<S>(subscriber: S)
where S: Combine.Subscriber, Publisher.Failure == S.Failure, Publisher.Output == S.Input {
publisher.receive(subscriber: SubscriberAdapter.subscriber(subscriber))
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension PublisherAdapter: OpenCombine.Publisher where Publisher: Combine.Publisher {
public typealias Output = Publisher.Output
public typealias Failure = Publisher.Failure

public func receive<S>(subscriber: S)
where S: OpenCombine.Subscriber, Publisher.Failure == S.Failure, Publisher.Output == S.Input {
publisher.receive(subscriber: SubscriberAdapter.subscriber(subscriber))
}
}
#endif
65 changes: 65 additions & 0 deletions Sources/OpenCombineBridge/Subject+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public final class SubjectAdapter<Subject> {
internal init(_ subject: Subject) {
self.subject = subject
}

let subject: Subject
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubjectAdapter: Combine.Publisher where Subject: OpenCombine.Publisher {
public typealias Output = Subject.Output
public typealias Failure = Subject.Failure

public func receive<S>(subscriber: S)
where S: Combine.Subscriber, Subject.Failure == S.Failure, Subject.Output == S.Input {
subject.receive(subscriber: SubscriberAdapter.subscriber(subscriber))
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubjectAdapter: OpenCombine.Publisher where Subject: Combine.Publisher {
public typealias Output = Subject.Output
public typealias Failure = Subject.Failure

public func receive<S>(subscriber: S)
where S: OpenCombine.Subscriber, Subject.Failure == S.Failure, Subject.Output == S.Input {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 🚫 Line should be 90 characters or less: currently 92 characters (line_length)

subject.receive(subscriber: SubscriberAdapter.subscriber(subscriber))
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubjectAdapter: Combine.Subject where Subject: OpenCombine.Subject {
public func send(_ value: Subject.Output) {
subject.send(value)
}

public func send(completion: Combine.Subscribers.Completion<Subject.Failure>) {
subject.send(completion: completion.ocombine)
}

public func send(subscription: Combine.Subscription) {
subject.send(subscription: SubscriptionAdapter.subscription(subscription))
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubjectAdapter: OpenCombine.Subject where Subject: Combine.Subject {
public func send(_ value: Subject.Output) {
subject.send(value)
}

public func send(completion: OpenCombine.Subscribers.Completion<Subject.Failure>) {
subject.send(completion: completion.combine)
}

public func send(subscription: OpenCombine.Subscription) {
subject.send(subscription: SubscriptionAdapter.subscription(subscription))
}
}
#endif
94 changes: 94 additions & 0 deletions Sources/OpenCombineBridge/Subscriber+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct SubscriberAdapter<Subscriber> {
internal init(_ subscriber: Subscriber) {
self.subscriber = subscriber
}

public let subscriber: Subscriber
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter where Subscriber: OpenCombine.Subscriber {
public static func subscriber(
_ subscriber: Subscriber
) -> SubscriberAdapter<Subscriber> {
SubscriberAdapter<Subscriber>(subscriber)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter where Subscriber: Combine.Subscriber {
public static func subscriber(
_ subscriber: Subscriber
) -> SubscriberAdapter<Subscriber> {
SubscriberAdapter<Subscriber>(subscriber)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter: Combine.CustomCombineIdentifierConvertible
where Subscriber: OpenCombine.CustomCombineIdentifierConvertible {
public var combineIdentifier: Combine.CombineIdentifier {
subscriber.combineIdentifier.combine
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter: OpenCombine.CustomCombineIdentifierConvertible
where Subscriber: Combine.CustomCombineIdentifierConvertible {
public var combineIdentifier: OpenCombine.CombineIdentifier {
subscriber.combineIdentifier.ocombine
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter: OpenCombine.Subscriber
where Subscriber: Combine.Subscriber {
public typealias Input = Subscriber.Input
public typealias Failure = Subscriber.Failure

public var combineIdentifier: OpenCombine.CombineIdentifier {
subscriber.combineIdentifier.ocombine
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 🚫 Lines should not have trailing whitespace. (trailing_whitespace)

public func receive(subscription: OpenCombine.Subscription) {
subscriber.receive(subscription: SubscriptionAdapter.subscription(subscription))
}

public func receive(_ input: Subscriber.Input) -> OpenCombine.Subscribers.Demand {
return subscriber.receive(input).ocombine
}

public func receive(completion: OpenCombine.Subscribers.Completion<Subscriber.Failure>) {
subscriber.receive(completion: completion.combine)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension SubscriberAdapter: Combine.Subscriber
where Subscriber: OpenCombine.Subscriber {
public typealias Input = Subscriber.Input
public typealias Failure = Subscriber.Failure

public var combineIdentifier: Combine.CombineIdentifier {
subscriber.combineIdentifier.combine
}

public func receive(subscription: Combine.Subscription) {
subscriber.receive(subscription: SubscriptionAdapter.subscription(subscription))
}

public func receive(_ input: Subscriber.Input) -> Combine.Subscribers.Demand {
return subscriber.receive(input).combine
}

public func receive(completion: Combine.Subscribers.Completion<Subscriber.Failure>) {
subscriber.receive(completion: completion.ocombine)
}
}

#endif
28 changes: 28 additions & 0 deletions Sources/OpenCombineBridge/Subscribers.Completion+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension OpenCombine.Subscribers.Completion {
public var combine: Combine.Subscribers.Completion<Failure> {
switch self {
case .finished:
return .finished
case .failure(let error):
return .failure(error)
}
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Combine.Subscribers.Completion {
public var ocombine: OpenCombine.Subscribers.Completion<Failure> {
switch self {
case .finished:
return .finished
case .failure(let error):
return .failure(error)
}
}
}
#endif
34 changes: 34 additions & 0 deletions Sources/OpenCombineBridge/Subscribers.Demand+Adapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#if canImport(Combine) && canImport(OpenCombine)
import Combine
import OpenCombine

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private func _rawValue(for demand: Combine.Subscribers.Demand) -> UInt {
Mirror(reflecting: demand).children.first(where: { $0.label == "rawValue" })!.value as! UInt
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
private func _rawValue(for demand: OpenCombine.Subscribers.Demand) -> UInt {
Mirror(reflecting: demand).children.first(where: { $0.label == "rawValue" })!.value as! UInt
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension OpenCombine.Subscribers.Demand {
public var combine: Combine.Subscribers.Demand {
copyValue(
of: self,
as: Combine.Subscribers.Demand.none
)
}
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Combine.Subscribers.Demand {
public var ocombine: OpenCombine.Subscribers.Demand {
copyValue(
of: self,
as: OpenCombine.Subscribers.Demand.none
)
}
}
#endif
Loading