Skip to content

Commit

Permalink
Support buildOptional and buildEither (#10)
Browse files Browse the repository at this point in the history
* Support buildOptional and buildEither

* Avoid yield loops

Suggested-By: @gh123man

* Use assertChanRx

* Remove pending Tasks at end of tests
  • Loading branch information
Kuniwak authored Jul 11, 2024
1 parent c98d165 commit 37d32cf
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Sources/AsyncChannels/Select.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ public struct SelectCollector {
public static func buildBlock(_ handlers: [SelectHandler]...) -> [SelectHandler] {
return handlers.reduce([], +)
}

public static func buildOptional(_ handlers: [SelectHandler]?) -> [SelectHandler] {
return handlers ?? []
}

public static func buildEither(first handlers: [SelectHandler]) -> [SelectHandler] {
return handlers
}

public static func buildEither(second handlers: [SelectHandler]) -> [SelectHandler] {
return handlers
}
}

@inlinable
Expand Down
104 changes: 104 additions & 0 deletions Tests/AsyncChannelsTests/AsyncChannelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,110 @@ final class AsyncTest: XCTestCase {
let r = await result.reduce(into: []) { $0.append($1) }
XCTAssertEqual(["foo", "bar"].sorted(), r.sorted())
}

func testOptionalSomeSelect() async {
let a = Channel<String>()
let result = Channel<String>(capacity: 1)

Task {
await a <- "foo"
}

await select {
if true {
receive(a) { await result <- $0! }
}
}

result.close()

await assertChanRx(result, "foo")
}

func testOptionalNoneSelect() async throws {
let a = Channel<String>()
let done = Channel<String>()

Task {
await a <- "foo"
}

Task {
await select {
if false {
receive(a) { XCTFail() }
}
none {
await done <- "done"
}
}
}

await <-done
await <-a
}

func testEitherIfSelect() async {
let a = Channel<String>()
let b = Channel<String>()
let result = Channel<String>(capacity: 1)

Task {
await a <- "foo"
}

Task {
await b <- "bar"
}

await select {
if false {
receive(a) { await result <- $0! }
} else {
receive(b) { await result <- $0! }
}
}

result.close()

await assertChanRx(result, "bar")
await <-a
}

func testEitherSwitchSelect() async {
let a = Channel<String>()
let b = Channel<String>()
let c = Channel<String>()
let result = Channel<String>(capacity: 2)
let x = 0

Task {
await a <- "foo"
}
Task {
await b <- "bar"
}
Task {
await c <- "baz"
}

await select {
switch x {
case 0:
receive(a) { await result <- $0! }
case 1:
receive(b) { await result <- $0! }
default:
receive(c) { await result <- $0! }
}
}

result.close()

await assertChanRx(result, "foo")
await <-b
await <-c
}

func testBufferSelect() async {
let c = Channel<String>(capacity: 3)
Expand Down

0 comments on commit 37d32cf

Please sign in to comment.