Skip to content

Commit 31e611e

Browse files
authored
Adds Optional.publisher as a convenience for Optional.Publisher.init. (#32)
1 parent a74c55a commit 31e611e

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

CombineExt.xcodeproj/project.pbxproj

+16
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
BF9D85D724450090001783E6 /* ShareReplayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9D85D624450090001783E6 /* ShareReplayTests.swift */; };
6161
BFB4EA132428256B0096E9E9 /* CombineLatestMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB4EA122428256B0096E9E9 /* CombineLatestMany.swift */; };
6262
BFB4EA1524283ECF0096E9E9 /* CombineLatestManyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB4EA1424283ECF0096E9E9 /* CombineLatestManyTests.swift */; };
63+
BFF0BFF12469D7D800399570 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0BFF02469D7D800399570 /* Optional.swift */; };
64+
BFF0BFF52469D92C00399570 /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0BFF42469D92C00399570 /* OptionalTests.swift */; };
6365
DC16910F24281A1800B234C4 /* MapMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC16910E24281A1800B234C4 /* MapMany.swift */; };
6466
DC1691122428228200B234C4 /* MapManyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1691112428228200B234C4 /* MapManyTests.swift */; };
6567
OBJ_22 /* AssignToMany.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AssignToMany.swift */; };
@@ -117,6 +119,8 @@
117119
BF9D85D624450090001783E6 /* ShareReplayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareReplayTests.swift; sourceTree = "<group>"; };
118120
BFB4EA122428256B0096E9E9 /* CombineLatestMany.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineLatestMany.swift; sourceTree = "<group>"; };
119121
BFB4EA1424283ECF0096E9E9 /* CombineLatestManyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineLatestManyTests.swift; sourceTree = "<group>"; };
122+
BFF0BFF02469D7D800399570 /* Optional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = "<group>"; };
123+
BFF0BFF42469D92C00399570 /* OptionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalTests.swift; sourceTree = "<group>"; };
120124
"CombineExt::CombineExt::Product" /* CombineExt.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CombineExt.framework; sourceTree = BUILT_PRODUCTS_DIR; };
121125
"CombineExt::CombineExtTests::Product" /* CombineExtTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = CombineExtTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
122126
DC16910E24281A1800B234C4 /* MapMany.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapMany.swift; sourceTree = "<group>"; };
@@ -190,6 +194,14 @@
190194
path = Subjects;
191195
sourceTree = "<group>";
192196
};
197+
BFF0BFEF2469D7A500399570 /* Convenience */ = {
198+
isa = PBXGroup;
199+
children = (
200+
BFF0BFF02469D7D800399570 /* Optional.swift */,
201+
);
202+
path = Convenience;
203+
sourceTree = "<group>";
204+
};
193205
OBJ_11 /* Tests */ = {
194206
isa = PBXGroup;
195207
children = (
@@ -212,6 +224,7 @@
212224
BF9D85D42444D12F001783E6 /* ReplaySubjectTests.swift */,
213225
BF9D85D624450090001783E6 /* ShareReplayTests.swift */,
214226
BF8EDF4D2453540D00B0CC75 /* PrefixDurationTests.swift */,
227+
BFF0BFF42469D92C00399570 /* OptionalTests.swift */,
215228
);
216229
path = Tests;
217230
sourceTree = SOURCE_ROOT;
@@ -240,6 +253,7 @@
240253
OBJ_7 /* Sources */ = {
241254
isa = PBXGroup;
242255
children = (
256+
BFF0BFEF2469D7A500399570 /* Convenience */,
243257
BF9D85D12444BB7F001783E6 /* Subjects */,
244258
78C193DA241D07160001B7FD /* Common */,
245259
78C193D5241C2E4F0001B7FD /* Models */,
@@ -378,6 +392,7 @@
378392
files = (
379393
BF3C6B6C24421D27004D4A8A /* ShareReplay.swift in Sources */,
380394
DC16910F24281A1800B234C4 /* MapMany.swift in Sources */,
395+
BFF0BFF12469D7D800399570 /* Optional.swift in Sources */,
381396
78C193CF241C16C40001B7FD /* FlatMapLatest.swift in Sources */,
382397
78C193DC241D0A9F0001B7FD /* Sink.swift in Sources */,
383398
788CD8FB2431228C0015B3C7 /* Amb.swift in Sources */,
@@ -416,6 +431,7 @@
416431
buildActionMask = 0;
417432
files = (
418433
78C193D2241C1B750001B7FD /* FlatMapLatestTests.swift in Sources */,
434+
BFF0BFF52469D92C00399570 /* OptionalTests.swift in Sources */,
419435
78AA9297241B8532009BD68B /* AssignToManyTests.swift in Sources */,
420436
BFB4EA1524283ECF0096E9E9 /* CombineLatestManyTests.swift in Sources */,
421437
71E6F4EE2465616100FB4103 /* AssignOwnershipTests.swift in Sources */,

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ All operators, utilities and helpers respect Combine's publisher contract, inclu
4545
### Subjects
4646
* [ReplaySubject](#ReplaySubject)
4747

48+
### Convenience
49+
* [Optional.publisher](#Optionalpublisher)
50+
4851
> **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! :)
4952
5053
## Installation
@@ -642,6 +645,28 @@ subject.send(5)
642645
5
643646
```
644647

648+
## Convenience
649+
650+
## Optional.publisher
651+
652+
`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).
653+
654+
So you can use:
655+
656+
```swift
657+
let number: Int? = 1
658+
number.publisher
659+
/**/
660+
```
661+
662+
Instead of:
663+
664+
```swift
665+
let number: Int? = 1
666+
Optional.Publisher(number)
667+
/**/
668+
```
669+
645670
## License
646671

647672
MIT, of course ;-) See the [LICENSE](LICENSE) file.

Sources/Convenience/Optional.swift

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// Optional.swift
3+
// CombineExt
4+
//
5+
// Created by Jasdev Singh on 11/05/2020.
6+
// Copyright © 2020 Combine Community. All rights reserved.
7+
//
8+
9+
#if canImport(Combine)
10+
import Combine
11+
12+
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
13+
public extension Optional {
14+
/// A publisher that publishes an optional value to each subscriber exactly once, if the optional has a value.
15+
var publisher: Optional.Publisher {
16+
Optional.Publisher(self)
17+
}
18+
}
19+
#endif

Tests/OptionalTests.swift

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// OptionalTests.swift
3+
// CombineExt
4+
//
5+
// Created by Jasdev Singh on 11/05/2020.
6+
// Copyright © 2020 Combine Community. All rights reserved.
7+
//
8+
9+
#if !os(watchOS)
10+
import Combine
11+
import CombineExt
12+
import XCTest
13+
14+
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
15+
final class OptionalTests: XCTestCase {
16+
private var subscription: AnyCancellable!
17+
18+
func testSomeInitialization() {
19+
var results = [Int]()
20+
var completion: Subscribers.Completion<Never>?
21+
22+
subscription = Optional(1)
23+
.publisher
24+
.sink(receiveCompletion: { completion = $0 },
25+
receiveValue: { results.append($0) })
26+
27+
XCTAssertEqual([1], results)
28+
XCTAssertEqual(.finished, completion)
29+
}
30+
31+
func testNoneInitialization() {
32+
var results = [Int]()
33+
var completion: Subscribers.Completion<Never>?
34+
35+
subscription = Optional<Int>.none
36+
.publisher
37+
.sink(receiveCompletion: { completion = $0 },
38+
receiveValue: { results.append($0) })
39+
40+
XCTAssertTrue(results.isEmpty)
41+
XCTAssertEqual(.finished, completion)
42+
}
43+
}
44+
#endif

Tests/PrefixDurationTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class PrefixDurationTests: XCTestCase {
4747
var completions = [Subscribers.Completion<Never>]()
4848

4949
cancellable = subject
50-
.prefix(duration: 0.5)
50+
.prefix(duration: 0.8)
5151
.sink(receiveCompletion: { completions.append($0); expectation.fulfill() },
5252
receiveValue: { results.append($0) })
5353

@@ -61,7 +61,7 @@ final class PrefixDurationTests: XCTestCase {
6161
subject.send(3)
6262
}
6363

64-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
64+
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
6565
subject.send(4)
6666
subject.send(5)
6767
subject.send(completion: .finished)

0 commit comments

Comments
 (0)