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

Adds Optional.publisher as a convenience for Optional.Publisher.init. #32

Merged
merged 1 commit into from
May 17, 2020
Merged
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
16 changes: 16 additions & 0 deletions CombineExt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
BF9D85D724450090001783E6 /* ShareReplayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9D85D624450090001783E6 /* ShareReplayTests.swift */; };
BFB4EA132428256B0096E9E9 /* CombineLatestMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB4EA122428256B0096E9E9 /* CombineLatestMany.swift */; };
BFB4EA1524283ECF0096E9E9 /* CombineLatestManyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB4EA1424283ECF0096E9E9 /* CombineLatestManyTests.swift */; };
BFF0BFF12469D7D800399570 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0BFF02469D7D800399570 /* Optional.swift */; };
BFF0BFF52469D92C00399570 /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0BFF42469D92C00399570 /* OptionalTests.swift */; };
DC16910F24281A1800B234C4 /* MapMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC16910E24281A1800B234C4 /* MapMany.swift */; };
DC1691122428228200B234C4 /* MapManyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1691112428228200B234C4 /* MapManyTests.swift */; };
OBJ_22 /* AssignToMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AssignToMany.swift */; };
Expand Down Expand Up @@ -117,6 +119,8 @@
BF9D85D624450090001783E6 /* ShareReplayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareReplayTests.swift; sourceTree = "<group>"; };
BFB4EA122428256B0096E9E9 /* CombineLatestMany.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineLatestMany.swift; sourceTree = "<group>"; };
BFB4EA1424283ECF0096E9E9 /* CombineLatestManyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineLatestManyTests.swift; sourceTree = "<group>"; };
BFF0BFF02469D7D800399570 /* Optional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = "<group>"; };
BFF0BFF42469D92C00399570 /* OptionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalTests.swift; sourceTree = "<group>"; };
"CombineExt::CombineExt::Product" /* CombineExt.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CombineExt.framework; sourceTree = BUILT_PRODUCTS_DIR; };
"CombineExt::CombineExtTests::Product" /* CombineExtTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = CombineExtTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DC16910E24281A1800B234C4 /* MapMany.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapMany.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -190,6 +194,14 @@
path = Subjects;
sourceTree = "<group>";
};
BFF0BFEF2469D7A500399570 /* Convenience */ = {
isa = PBXGroup;
children = (
BFF0BFF02469D7D800399570 /* Optional.swift */,
);
path = Convenience;
sourceTree = "<group>";
};
OBJ_11 /* Tests */ = {
isa = PBXGroup;
children = (
Expand All @@ -212,6 +224,7 @@
BF9D85D42444D12F001783E6 /* ReplaySubjectTests.swift */,
BF9D85D624450090001783E6 /* ShareReplayTests.swift */,
BF8EDF4D2453540D00B0CC75 /* PrefixDurationTests.swift */,
BFF0BFF42469D92C00399570 /* OptionalTests.swift */,
);
path = Tests;
sourceTree = SOURCE_ROOT;
Expand Down Expand Up @@ -240,6 +253,7 @@
OBJ_7 /* Sources */ = {
isa = PBXGroup;
children = (
BFF0BFEF2469D7A500399570 /* Convenience */,
BF9D85D12444BB7F001783E6 /* Subjects */,
78C193DA241D07160001B7FD /* Common */,
78C193D5241C2E4F0001B7FD /* Models */,
Expand Down Expand Up @@ -378,6 +392,7 @@
files = (
BF3C6B6C24421D27004D4A8A /* ShareReplay.swift in Sources */,
DC16910F24281A1800B234C4 /* MapMany.swift in Sources */,
BFF0BFF12469D7D800399570 /* Optional.swift in Sources */,
78C193CF241C16C40001B7FD /* FlatMapLatest.swift in Sources */,
78C193DC241D0A9F0001B7FD /* Sink.swift in Sources */,
788CD8FB2431228C0015B3C7 /* Amb.swift in Sources */,
Expand Down Expand Up @@ -416,6 +431,7 @@
buildActionMask = 0;
files = (
78C193D2241C1B750001B7FD /* FlatMapLatestTests.swift in Sources */,
BFF0BFF52469D92C00399570 /* OptionalTests.swift in Sources */,
78AA9297241B8532009BD68B /* AssignToManyTests.swift in Sources */,
BFB4EA1524283ECF0096E9E9 /* CombineLatestManyTests.swift in Sources */,
71E6F4EE2465616100FB4103 /* AssignOwnershipTests.swift in Sources */,
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ All operators, utilities and helpers respect Combine's publisher contract, inclu
### Subjects
* [ReplaySubject](#ReplaySubject)

### Convenience
* [Optional.publisher](#Optionalpublisher)

> **Note**: This is still a relatively early version of CombineExt, with much more to be desired. I gladly accept PRs, ideas, opinions, or improvements. Thank you! :)

## Installation
Expand Down Expand Up @@ -642,6 +645,28 @@ subject.send(5)
5
```

## Convenience

## Optional.publisher

`Optional.publisher` is a property version of [`Optional.Publisher.init`](https://developer.apple.com/documentation/swift/optional/publisher/3343960-init). It puts the type on equal footing with [`Result.publisher`](https://developer.apple.com/documentation/swift/result/3344716-publisher) and [`Sequence.publisher`](https://developer.apple.com/documentation/swift/sequence/3344717-publisher).

So you can use:

```swift
let number: Int? = 1
number.publisher
/* … */
```

Instead of:

```swift
let number: Int? = 1
Optional.Publisher(number)
/* … */
```

## License

MIT, of course ;-) See the [LICENSE](LICENSE) file.
Expand Down
19 changes: 19 additions & 0 deletions Sources/Convenience/Optional.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Optional.swift
// CombineExt
//
// Created by Jasdev Singh on 11/05/2020.
// Copyright © 2020 Combine Community. All rights reserved.
//

#if canImport(Combine)
import Combine

@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public extension Optional {
/// A publisher that publishes an optional value to each subscriber exactly once, if the optional has a value.
var publisher: Optional.Publisher {
Optional.Publisher(self)
}
}
#endif
44 changes: 44 additions & 0 deletions Tests/OptionalTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// OptionalTests.swift
// CombineExt
//
// Created by Jasdev Singh on 11/05/2020.
// Copyright © 2020 Combine Community. All rights reserved.
//

#if !os(watchOS)
import Combine
import CombineExt
import XCTest

@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
final class OptionalTests: XCTestCase {
private var subscription: AnyCancellable!

func testSomeInitialization() {
var results = [Int]()
var completion: Subscribers.Completion<Never>?

subscription = Optional(1)
.publisher
.sink(receiveCompletion: { completion = $0 },
receiveValue: { results.append($0) })

XCTAssertEqual([1], results)
XCTAssertEqual(.finished, completion)
}

func testNoneInitialization() {
var results = [Int]()
var completion: Subscribers.Completion<Never>?

subscription = Optional<Int>.none
.publisher
.sink(receiveCompletion: { completion = $0 },
receiveValue: { results.append($0) })

XCTAssertTrue(results.isEmpty)
XCTAssertEqual(.finished, completion)
Copy link
Member

Choose a reason for hiding this comment

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

the docs mention this could end with an error, not sure if this is related to nullabiilty or just something confusing about the docs. I imagine it's just gonna compete without anything if it's nil?

Copy link
Member Author

Choose a reason for hiding this comment

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

Optional.Publisher.Failure is Never, so it can’t error. 😄

https://developer.apple.com/documentation/swift/optional/publisher/failure

Copy link
Member

Choose a reason for hiding this comment

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

}
}
#endif
4 changes: 2 additions & 2 deletions Tests/PrefixDurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class PrefixDurationTests: XCTestCase {
var completions = [Subscribers.Completion<Never>]()

cancellable = subject
.prefix(duration: 0.5)
.prefix(duration: 0.8)
Copy link
Member

Choose a reason for hiding this comment

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

Sneaky you

.sink(receiveCompletion: { completions.append($0); expectation.fulfill() },
receiveValue: { results.append($0) })

Expand All @@ -61,7 +61,7 @@ final class PrefixDurationTests: XCTestCase {
subject.send(3)
}

DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
subject.send(4)
subject.send(5)
subject.send(completion: .finished)
Expand Down