Skip to content

Commit

Permalink
doc: refactor documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rockmagma02 committed Jun 26, 2024
1 parent 1943d5d commit 703e0d2
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 158 deletions.
12 changes: 8 additions & 4 deletions Sources/BidirectionalStream/BidirectionalAsyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public class BidirectionalAsyncStream<YieldT, SendT, ReturnT> {
/// Creates a new `BidirectionalSyncStream`.
///
/// - Parameters:
/// - YieldT: The type of the value to yield.
/// - SendT: The type of the value to send.
/// - ReturnT: The type of the value to return.
/// - build: A async closure that takes a `Continuation` and returns `Void`.
/// - The type of the value to yield.
/// - The type of the value to send.
/// - The type of the value to return.
/// - A async closure that takes a `Continuation` and returns `Void`.
public init(
_: YieldT.Type = YieldT.self,
_: SendT.Type = SendT.self,
Expand Down Expand Up @@ -203,6 +203,10 @@ public extension BidirectionalAsyncStream {
///
/// - Parameters:
/// - error: The error to throw.
/// - fileName: The name of the file where the error was thrown.
/// - functionName: The name of the function where the error was thrown.
/// - lineNumber: The line number where the error was thrown.
/// - columnNumber: The column number where the error was thrown.
public func `throw`(
error: any Error,
fileName: String = #file,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# ``BidirectionalStream``

`BidirectionalStream` aims to bring features similar to Python's Generator to Swift. Users can generate values using `yield`, send values back with `send`, and close the stream by throwing a `StopIteration` error.

## Overview

Inspired by Python generators, which not only can use `yield` to produce values, but also can use `send` to receive values, and `return` to raise a `StopIteration` error and halt the stream, the ``BidirectionalSyncStream`` and ``BidirectionalAsyncStream`` in Swift offer similar features for synchronous and asynchronous operations respectively.

For more information about the generator in python, See: [PEP 255](https://peps.python.org/pep-0255/), [PEP 342](https://peps.python.org/pep-0342/#new-generator-method-send-value), [Doc](https://docs.python.org/3/reference/expressions.html#generator-iterator-methods)

## Getting Started

In the following example, the stream uses the `send(_:)` method to send a value back to the stream, which is received by the `yield(_:)` return value.

```swift
let stream = BidirectionalSyncStream<Int, Int, NoneType> { continuation in
var value = 0
while true {
value = continuation.yield(value)
value += 1
}
}

try stream.next() // 0 start the stream
try stream.send(5) // 6 send value back to the stream, and get the next value
```

In the following example, when the stream's closure uses `return(_:)` to stop the streaming process, a `StopIteration` error containing the return value will be caught outside the closure.

```swift
let stream = BidirectionalSyncStream<Int, Int, String> { continuation in
var value = 0
while true {
value = continuation.yield(value)
value += 1
if value == 5 {
continuation.return("Stop")
}
}
}

try stream.next() // 0 start the stream
do {
try stream.send(4) // Throw StopIteration error
} catch {
// get return value
print((error as! StopIteration).value) // "Stop"
}
```

## Topics

### Supporting Types

+ ``NoneType``
+ ``StopIteration``
+ ``Terminated``
+ ``WrongStreamUse``
+ ``AsyncSemaphore``

### BidirectionalStream

+ ``BidirectionalSyncStream``
+ ``BidirectionalAsyncStream``
16 changes: 10 additions & 6 deletions Sources/BidirectionalStream/BidirectionalSyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import SyncStream

// MARK: - StopIteration

/// A special error to indicate the end of the stream.
/// A special error containing the return value to indicate the end of the stream.
public struct StopIteration<ReturnT>: Error {
public var value: ReturnT
}
Expand All @@ -33,7 +33,7 @@ public struct WrongStreamUse: Error {
// MARK: - Terminated

/// An error to indicate that the stream has been terminated.
/// i.e. an error has occurred in the stream.
/// i.e. an error has occurred in the stream's inside closure.
public struct Terminated: Error {
/// The file name where the error occurred.
public var fileName: String
Expand Down Expand Up @@ -70,10 +70,10 @@ public class BidirectionalSyncStream<YieldT, SendT, ReturnT> {
/// Creates a new `BidirectionalSyncStream`.
///
/// - Parameters:
/// - YieldT: The type of the value to yield.
/// - SendT: The type of the value to send.
/// - ReturnT: The type of the value to return.
/// - build: A closure that takes a `Continuation` and returns `Void`.
/// - The type of the value to yield.
/// - The type of the value to send.
/// - The type of the value to return.
/// - A closure that takes a `Continuation` and returns `Void`.
public init(
_: YieldT.Type = YieldT.self,
_: SendT.Type = SendT.self,
Expand Down Expand Up @@ -250,6 +250,10 @@ public extension BidirectionalSyncStream {
///
/// - Parameters:
/// - error: The error to throw.
/// - fileName: The name of the file where the error was thrown.
/// - functionName: The name of the function where the error was thrown.
/// - lineNumber: The line number where the error was thrown.
/// - columnNumber: The column number where the error was thrown.
public func `throw`(
error: any Error,
fileName: String = #file,
Expand Down
67 changes: 0 additions & 67 deletions Sources/SyncStream/SyncStream.docc/BidirectionalSyncStream.md

This file was deleted.

28 changes: 28 additions & 0 deletions Sources/SyncStream/SyncStream.docc/LandingPage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# ``SyncStream``

`SyncStream` is a class that generates a sequence of values, inspired by `AsyncStream` from the swift standard library.

## Overview

[`AsyncStream`](https://developer.apple.com/documentation/swift/asyncstream) offers a convenient method to create a sequence from a closure that invokes a continuation to generate elements. However, in certain cases, you may need to produce a sequence synchronously using a closure. To address this need, we introduce [`SyncStream`](syncstream/syncstream), which shares the same API as `AsyncStream` but operates synchronously.

Here is a simple example of how to use `SyncStream`:

```swift
let stream = SyncStream<Int> { continuation in
for i in 0 ..< 10 {
continuation.yield(i)
}
continuation.finish()
}

for value in stream {
print(value, terminator: " ")
}
// 0 1 2 3 4 5 6 7 8 9
```

## Topics

+ ``SyncStream-class``
+ ``SyncStream/Continuation``
72 changes: 0 additions & 72 deletions Sources/SyncStream/SyncStream.docc/SyncStream.md

This file was deleted.

17 changes: 10 additions & 7 deletions Sources/SyncStream/SyncStream.docc/SyncStreamClass.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

## Overview

[SyncStream](syncstream/syncstream) is inspired by Swift's [`AsyncStream`](https://developer.apple.com/documentation/swift/asyncstream) and offers a convenient way to generate a sequence using a closure, without the need to implement the `Sequence` protocol.
[`AsyncStream`](https://developer.apple.com/documentation/swift/asyncstream) offers a convenient method to create a sequence from a closure that invokes a continuation to generate elements. However, in certain cases, you may need to produce a sequence synchronously using a closure. To address this need, we introduce [`SyncStream`](syncstream/syncstream), which shares the same API as `AsyncStream` but operates synchronously.

Just like the [`AsyncStream`](https://developer.apple.com/documentation/swift/asyncstream) , the [SyncStream](syncstream/syncstream) also utilizes a class called [Continuation](syncstream/syncstream/continuation) to manage the production progress. The [Continuation](syncstream/syncstream/continuation) offers two main methods, [`yield(_:)`](syncstream/syncstream/continuation/yield(_:)) and [`finish`](syncstream/syncstream/continuation/finish()), similar to those in the [`AsyncStream`](https://developer.apple.com/documentation/swift/asyncstream), but operates synchronously. If you are familiar with Python, you can consider the [SyncStream](syncstream/syncstream) as a generator.
In detail, the most common way to initialize a `SyncStream` is providing a closure that takes a `Continuation` argument. The `Continuation` class provides two key methods, `yield(_:)` and `finish()`, to manage the element production procedure.

Because of the synchronous feature, the closure will not execute until you start iterating over the stream.

```swift
let stream = SyncStream<Int> { continuation in
Expand All @@ -15,7 +17,7 @@ let stream = SyncStream<Int> { continuation in
}

for value in stream {
print(value, terminator: " ")
print(value, terminator: " ")
}
// 0 1 2 3 4 5 6 7 8 9
```
Expand Down Expand Up @@ -48,13 +50,14 @@ print(value, terminator: " ")

- ``dropFirst(_:)``
- ``drop(while:)``
- ``filter(_:)``
- ``filter(_:)-6h5ix``
- ``filter(_:)-7wb05``

### Transforming a Sequence

- ``map(_:)-hk46``
- ``map(_:)-5vrbe``
- ``map(_:)``
- ``compactMap(_:)``
- ``flatMap(_:)``
- ``flatMap(_:)-uifn``
- ``flatMap(_:)-5btn7``
- ``reduce(_:_:)``
- ``reduce(into:_:)``
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

The Closure you provide to the `SyncStream` in `init(_:_:)` received an instance of this type when called. Use this continuation to yield element via method `yield(_)`, and finish the stream via method `finish()`.
The `Closure` used in the `SyncStream` takes an argument of `Continuation`, which provides the methods `yield(_:)` and `finish()` to produce elements and finish the stream.

## Topics

Expand Down
2 changes: 1 addition & 1 deletion Sources/SyncStream/SyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class SyncStream<Element>: Sequence, IteratorProtocol {
// MARK: Public

/// Constructs an synchronous stream from the Element Type
/// - Parameter type: The Element Type
/// - Parameter of: The Element Type
///
/// - Returns: A tuple containing the stream and its continuation. The continuation
/// should be passed to the producer while the stream should be passed to the consumer.
Expand Down

0 comments on commit 703e0d2

Please sign in to comment.