Skip to content

Commit ffadaf3

Browse files
committed
Some code blocks and some credits
1 parent be6ee0f commit ffadaf3

File tree

9 files changed

+536
-7
lines changed

9 files changed

+536
-7
lines changed

Guides/Chunked.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,182 @@
1515

1616
## Proposed Solution
1717

18+
### Grouping
19+
20+
```swift
21+
extension AsyncSequence {
22+
@inlinable
23+
public func chunked<Collected: RangeReplaceableCollection>(
24+
by belongInSameGroup: @escaping @Sendable (Element, Element) -> Bool,
25+
collectedInto: Collected.Type
26+
) -> AsyncChunkedByGroupSequence<Self, Collected>
27+
where Collected.Element == Element
28+
29+
public func chunked(
30+
by belongInSameGroup: @escaping @Sendable (Element, Element) -> Bool
31+
) -> AsyncChunkedByGroupSequence<Self, [Element]>
32+
}
33+
```
34+
35+
### Projected Seperator
36+
37+
```swift
38+
extension AsyncSequence {
39+
public func chunked<Subject : Equatable, Collected: RangeReplaceableCollection>(
40+
on projection: @escaping @Sendable (Element) -> Subject,
41+
collectedInto: Collected.Type
42+
) -> AsyncChunkedOnProjectionSequence<Self, Subject, Collected>
43+
where Collected.Element == Element
44+
45+
public func chunked<Subject : Equatable>(
46+
on projection: @escaping @Sendable (Element) -> Subject
47+
) -> AsyncChunkedOnProjectionSequence<Self, Subject, [Element]>
48+
}
49+
```
50+
51+
### Count or Signal
52+
53+
```swift
54+
extension AsyncSequence {
55+
public func chunked<Signal, Collected: RangeReplaceableCollection>(
56+
byCount count: Int,
57+
andSignal signal: Signal,
58+
collectedInto: Collected.Type
59+
) -> AsyncChunksOfCountAndSignalSequence<Self, Collected, Signal>
60+
where Collected.Element == Element
61+
62+
public func chunked<Signal>(
63+
byCount count: Int,
64+
andSignal signal: Signal
65+
) -> AsyncChunksOfCountAndSignalSequence<Self, [Element], Signal>
66+
67+
public func chunked<Signal, Collected: RangeReplaceableCollection>(
68+
bySignal signal: Signal,
69+
collectedInto: Collected.Type
70+
) -> AsyncChunksOfCountAndSignalSequence<Self, Collected, Signal>
71+
where Collected.Element == Element
72+
73+
public func chunked<Signal>(
74+
bySignal signal: Signal) -> AsyncChunksOfCountAndSignalSequence<Self, [Element], Signal>
75+
76+
public func chunked<C: Clock, Collected: RangeReplaceableCollection>(
77+
byCount count: Int,
78+
andTime timer: AsyncTimerSequence<C>,
79+
collectedInto: Collected.Type
80+
) -> AsyncChunksOfCountAndSignalSequence<Self, Collected, AsyncTimerSequence<C>>
81+
where Collected.Element == Element
82+
83+
public func chunked<C: Clock>(
84+
byCount count: Int,
85+
andTime timer: AsyncTimerSequence<C>
86+
) -> AsyncChunksOfCountAndSignalSequence<Self, [Element], AsyncTimerSequence<C>>
87+
88+
public func chunked<C: Clock, Collected: RangeReplaceableCollection>(
89+
byTime timer: AsyncTimerSequence<C>,
90+
collectedInto: Collected.Type
91+
) -> AsyncChunksOfCountAndSignalSequence<Self, Collected, AsyncTimerSequence<C>>
92+
where Collected.Element == Element
93+
94+
public func chunked<C: Clock>(
95+
byTime timer: AsyncTimerSequence<C>
96+
) -> AsyncChunksOfCountAndSignalSequence<Self, [Element], AsyncTimerSequence<C>>
97+
}
98+
99+
extension AsyncSequence {
100+
public func chunks<Collected: RangeReplaceableCollection>(
101+
ofCount count: Int,
102+
collectedInto: Collected.Type
103+
) -> AsyncChunksOfCountSequence<Self, [Element]>
104+
where Collected.Element == Element
105+
106+
public func chunks(
107+
ofCount count: Int
108+
) -> AsyncChunksOfCountSequence<Self, [Element]>
109+
}
110+
```
111+
18112
## Detailed Design
19113

114+
### Grouping
115+
116+
```swift
117+
public struct AsyncChunkedByGroupSequence<Base: AsyncSequence, Collected: RangeReplaceableCollection>: AsyncSequence
118+
where Collected.Element == Base.Element {
119+
public typealias Element = Collected {
120+
121+
public struct Iterator: AsyncIteratorProtocol {
122+
public mutating func next() async rethrows -> Collected?
123+
}
124+
125+
public func makeAsyncIterator() -> Iterator
126+
}
127+
128+
extension AsyncChunkedByGroupSequence: Sendable
129+
where Base: Sendable, Base.Element: Sendable { }
130+
131+
extension AsyncChunkedByGroupSequence.Iterator: Sendable
132+
where Base.AsyncIterator: Sendable, Base.Element: Sendable { }
133+
```
134+
135+
### Projected Seperator
136+
137+
```swift
138+
public struct AsyncChunkedOnProjectionSequence<Base: AsyncSequence, Subject: Equatable, Collected: RangeReplaceableCollection>: AsyncSequence where Collected.Element == Base.Element {
139+
public typealias Element = (Subject, Collected)
140+
141+
public struct Iterator: AsyncIteratorProtocol {
142+
public mutating func next() async rethrows -> (Subject, Collected)?
143+
}
144+
145+
public func makeAsyncIterator() -> Iterator
146+
}
147+
148+
extension AsyncChunkedOnProjectionSequence: Sendable
149+
where Base: Sendable, Base.Element: Sendable { }
150+
extension AsyncChunkedOnProjectionSequence.Iterator: Sendable
151+
where Base.AsyncIterator: Sendable, Base.Element: Sendable, Subject: Sendable { }
152+
```
153+
154+
### Count
155+
156+
```swift
157+
public struct AsyncChunksOfCountSequence<Base: AsyncSequence, Collected: RangeReplaceableCollection>: AsyncSequence
158+
where Collected.Element == Base.Element {
159+
public typealias Element = Collected
160+
161+
public struct Iterator: AsyncIteratorProtocol {
162+
public mutating func next() async rethrows -> Collected?
163+
}
164+
165+
public func makeAsyncIterator() -> Iterator
166+
}
167+
168+
extension AsyncChunksOfCountSequence : Sendable where Base : Sendable, Base.Element : Sendable { }
169+
extension AsyncChunksOfCountSequence.Iterator : Sendable where Base.AsyncIterator : Sendable, Base.Element : Sendable { }
170+
171+
```
172+
173+
### Count or Signal
174+
175+
```swift
176+
public struct AsyncChunksOfCountAndSignalSequence<Base: AsyncSequence, Collected: RangeReplaceableCollection, Signal: AsyncSequence>: AsyncSequence, Sendable
177+
where
178+
Collected.Element == Base.Element,
179+
Base: Sendable, Signal: Sendable,
180+
Base.AsyncIterator: Sendable, Signal.AsyncIterator: Sendable,
181+
Base.Element: Sendable, Signal.Element: Sendable {
182+
public typealias Element = Collected
183+
184+
public struct Iterator: AsyncIteratorProtocol, Sendable {
185+
public mutating func next() async rethrows -> Collected?
186+
}
187+
188+
public func makeAsyncIterator() -> Iterator
189+
}
190+
```
191+
192+
## Alternatives Considered
193+
20194
## Credits/Inspiration
21195

196+
This transformation function is a direct analog to the synchronous version [defined in the Swift Algorithms package](https://github.com/apple/swift-algorithms/blob/main/Guides/Chunked.md)

Guides/Collections.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Collection and Sequence initializers
1+
# Collection Initializers
22

33
* Author(s): [Philippe Hausler](https://github.com/phausler)
44

@@ -14,8 +14,67 @@
1414

1515
## Introduction
1616

17+
`Array`, `Dictionary` and `Set` are some of the most commonly used data structures for storing collections of elements. Having a way to transition from an `AsyncSequence` to a collection is not only a useful shorthand but a powerful way of expressing direct intent for how to consume an `AsyncSequence`.
18+
19+
This type of functionality can be useful for examples, testing, but also interfacing with existing APIs that expect a fully formed collection before processing it.
20+
1721
## Proposed Solution
1822

23+
Three categories of initializers will be added to focus on ensuring initializers for those three primary types - `Array`, `Dictionary` and `Set`. However these initializers can be written in a generic fashon such that they can apply to all similar collections.
24+
25+
`RangeReplaceableCollection` will gain a new asynchronous initializer that rethrows; constructing a collection given an `AsyncSequence`. This will allow for creating arrays from asynchronous sequences but also allow for creating types like `Data` or `ContiguousArray`.
26+
27+
`Dictionary` will gain a family new asynchronous initializers to parallel the existing `Sequence` based initializers. The initializers will be asynchronous to facilitate uniquing keys and other tasks that may be asynchronous in addition to the asynchronous initialization of the dictionaries.
28+
29+
`SetAlgebra` will gain a new asynchronous initializer that rethrows; constructing that `SetAlgebra` type given an `AsyncSequence`. This will allow for creating sets from asynchronous sequences but also allow for creating types like `OptionSet` types or `IndexSet`.
30+
31+
### RangeReplaceableCollection
32+
33+
```swift
34+
extension RangeReplacableCollection {
35+
public init<Source: AsyncSequence>(
36+
_ source: Source
37+
) async rethrows
38+
where Source.Element == Element
39+
}
40+
```
41+
42+
### Dictionary
43+
44+
```swift
45+
extension Dictionary {
46+
public init<S: AsyncSequence>(
47+
uniqueKeysWithValues keysAndValues: S
48+
) async rethrows
49+
where S.Element == (Key, Value)
50+
51+
public init<S: AsyncSequence>(
52+
_ keysAndValues: S,
53+
uniquingKeysWith combine: (Value, Value) async throws -> Value
54+
) async rethrows
55+
where S.Element == (Key, Value)
56+
57+
public init<S: AsyncSequence>(
58+
grouping values: S,
59+
by keyForValue: (S.Element) async throws -> Key
60+
) async rethrows
61+
where Value == [S.Element]
62+
}
63+
```
64+
65+
### SetAlgebra
66+
67+
```swift
68+
extension SetAlgebra {
69+
public init<Source: AsyncSequence>(
70+
_ source: Source
71+
) async rethrows
72+
where Source.Element == Element
73+
}
74+
```
75+
1976
## Detailed Design
2077

78+
## Alternatives Considered
79+
2180
## Credits/Inspiration

Guides/Compacted.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,45 @@
77
[Tests](https://github.com/apple/swift-async-algorithms/blob/main/Tests/AsyncAlgorithmsTests/TestCompacted.swift)
88
]
99

10-
1110
## Introduction
1211

1312
## Proposed Solution
1413

14+
```swift
15+
extension AsyncSequence {
16+
public func compacted<Unwrapped>() -> AsyncCompactedSequence<Self, Unwrapped>
17+
where Element == Unwrapped?
18+
}
19+
```
20+
1521
## Detailed Design
1622

23+
```swift
24+
public struct AsyncCompactedSequence<Base: AsyncSequence, Element>: AsyncSequence
25+
where Base.Element == Element? {
26+
27+
public struct Iterator: AsyncIteratorProtocol {
28+
public mutating func next() async rethrows -> Element?
29+
}
30+
31+
public func makeAsyncIterator() -> Iterator {
32+
Iterator(base.makeAsyncIterator())
33+
}
34+
}
35+
36+
extension AsyncCompactedSequence: Sendable
37+
where
38+
Base: Sendable, Base.Element: Sendable,
39+
Base.AsyncIterator: Sendable { }
40+
41+
extension AsyncCompactedSequence.Iterator: Sendable
42+
where
43+
Base: Sendable, Base.Element: Sendable,
44+
Base.AsyncIterator: Sendable { }
45+
```
46+
47+
## Alternatives Considered
48+
1749
## Credits/Inspiration
50+
51+
This transformation function is a direct analog to the synchronous version [defined in the Swift Algorithms package](https://github.com/apple/swift-algorithms/blob/main/Guides/Compacted.md)

Guides/Debounce.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,38 @@
77
[Tests](https://github.com/apple/swift-async-algorithms/blob/main/Tests/AsyncAlgorithmsTests/TestDebounce.swift)
88
]
99

10-
1110
## Introduction
1211

1312
## Proposed Solution
1413

14+
```swift
15+
extension AsyncSequence {
16+
public func debounce<C: Clock>(
17+
for interval: C.Instant.Duration,
18+
tolerance: C.Instant.Duration? = nil,
19+
clock: C
20+
) -> AsyncDebounceSequence<Self, C>
21+
}
22+
```
23+
1524
## Detailed Design
1625

26+
```swift
27+
public struct AsyncDebounceSequence<Base: AsyncSequence, C: Clock>: Sendable
28+
where Base.AsyncIterator: Sendable, Base.Element: Sendable, Base: Sendable {
29+
}
30+
31+
extension AsyncDebounceSequence: AsyncSequence {
32+
public typealias Element = Base.Element
33+
34+
public struct Iterator: AsyncIteratorProtocol, Sendable {
35+
public mutating func next() async rethrows -> Base.Element?
36+
}
37+
38+
public func makeAsyncIterator() -> Iterator
39+
}
40+
```
41+
42+
## Alternatives Considered
43+
1744
## Credits/Inspiration

0 commit comments

Comments
 (0)