Skip to content

Commit 7f73349

Browse files
authored
Add primary associated types to property and binding protocols (#888)
* Add primary associated types to property and binding protocols - PropertyProtocol - MutablePropertyProtocol - ComposableMutablePropertyProtocol - BindingSource - BindingTargetProvider * Add entry to change log * Remove instructional text from the previous version in changelog * Replace uses of 'bond' with 'bound' in doc comments
1 parent 8581f24 commit 7f73349

File tree

3 files changed

+86
-6
lines changed

3 files changed

+86
-6
lines changed

CHANGELOG.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
# master
22
*Please add new entries at the top.*
3+
1. Add primary associated types to property and binding protocols (#888, kudos to @braker1nine)
34
1. Fix the Carthage build checks (kudos to @mluisbrown)
45
1. Add dynamic library support for SPM (#886 kudos to @mluisbrown)
56

67
# 7.2.0
7-
*Please add new entries at the top.*
8-
98
1. Change `QueueScheduler` to use unspecified QoS when QoS parameter is defaulted (#880, kudos to @jamieQ)
109
1. Add support for visionOS (#875, kudos to @NachoSoto)
1110
1. Fix CI release git tag push trigger (#869, kudos to @p4checo)

Sources/Property.swift

+67
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,35 @@ import Glibc
77
// FIXME: The `Error == Never` constraint is retained for Swift 4.0.x
88
// compatibility, since `BindingSource` did not impose such constraint
99
// due to the absence of conditional conformance.
10+
#if swift(>=5.7)
11+
12+
/// Represents a property that allows observation of its changes.
13+
///
14+
/// Only classes can conform to this protocol, because having a signal
15+
/// for changes over time implies the origin must have a unique identity.
16+
public protocol PropertyProtocol<Value>: AnyObject, BindingSource {
17+
/// The current value of the property.
18+
var value: Value { get }
19+
20+
/// The values producer of the property.
21+
///
22+
/// It produces a signal that sends the property's current value,
23+
/// followed by all changes over time. It completes when the property
24+
/// has deinitialized, or has no further change.
25+
///
26+
/// - note: If `self` is a composed property, the producer would be
27+
/// bound to the lifetime of its sources.
28+
var producer: SignalProducer<Value, Never> { get }
29+
30+
/// A signal that will send the property's changes over time. It
31+
/// completes when the property has deinitialized, or has no further
32+
/// change.
33+
///
34+
/// - note: If `self` is a composed property, the signal would be
35+
/// bound to the lifetime of its sources.
36+
var signal: Signal<Value, Never> { get }
37+
}
38+
#else
1039

1140
/// Represents a property that allows observation of its changes.
1241
///
@@ -34,7 +63,20 @@ public protocol PropertyProtocol: AnyObject, BindingSource {
3463
/// bound to the lifetime of its sources.
3564
var signal: Signal<Value, Never> { get }
3665
}
66+
#endif
3767

68+
#if swift(>=5.7)
69+
/// Represents an observable property that can be mutated directly.
70+
public protocol MutablePropertyProtocol<Value>: PropertyProtocol, BindingTargetProvider {
71+
associatedtype Value
72+
73+
/// The current value of the property.
74+
var value: Value { get set }
75+
76+
/// The lifetime of the property.
77+
var lifetime: Lifetime { get }
78+
}
79+
#else
3880
/// Represents an observable property that can be mutated directly.
3981
public protocol MutablePropertyProtocol: PropertyProtocol, BindingTargetProvider {
4082
/// The current value of the property.
@@ -43,6 +85,7 @@ public protocol MutablePropertyProtocol: PropertyProtocol, BindingTargetProvider
4385
/// The lifetime of the property.
4486
var lifetime: Lifetime { get }
4587
}
88+
#endif
4689

4790
/// Default implementation of `BindingTargetProvider` for mutable properties.
4891
extension MutablePropertyProtocol {
@@ -51,6 +94,29 @@ extension MutablePropertyProtocol {
5194
}
5295
}
5396

97+
#if swift(>=5.7)
98+
/// Represents a mutable property that can be safety composed by exposing its
99+
/// synchronization mechanic through the defined closure-based interface.
100+
public protocol ComposableMutablePropertyProtocol<Value>: MutablePropertyProtocol {
101+
/// Atomically performs an arbitrary action using the current value of the
102+
/// variable.
103+
///
104+
/// - parameters:
105+
/// - action: A closure that accepts current property value.
106+
///
107+
/// - returns: the result of the action.
108+
func withValue<Result>(_ action: (Value) throws -> Result) rethrows -> Result
109+
110+
/// Atomically modifies the variable.
111+
///
112+
/// - parameters:
113+
/// - action: A closure that accepts old property value and returns a new
114+
/// property value.
115+
///
116+
/// - returns: The result of the action.
117+
func modify<Result>(_ action: (inout Value) throws -> Result) rethrows -> Result
118+
}
119+
#else
54120
/// Represents a mutable property that can be safety composed by exposing its
55121
/// synchronization mechanic through the defined closure-based interface.
56122
public protocol ComposableMutablePropertyProtocol: MutablePropertyProtocol {
@@ -72,6 +138,7 @@ public protocol ComposableMutablePropertyProtocol: MutablePropertyProtocol {
72138
/// - returns: The result of the action.
73139
func modify<Result>(_ action: (inout Value) throws -> Result) rethrows -> Result
74140
}
141+
#endif
75142

76143
// Property operators.
77144
//

Sources/UnidirectionalBinding.swift

+18-4
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,31 @@ precedencegroup BindingPrecedence {
1010

1111
infix operator <~ : BindingPrecedence
1212

13+
#if swift(>=5.7)
14+
/// Describes a source which can be bound.
15+
public protocol BindingSource<Value>: SignalProducerConvertible where Error == Never {}
16+
#else
1317
/// Describes a source which can be bound.
1418
public protocol BindingSource: SignalProducerConvertible where Error == Never {}
19+
#endif
1520
extension Signal: BindingSource where Error == Never {}
1621
extension SignalProducer: BindingSource where Error == Never {}
1722

18-
/// Describes an entity which be bond towards.
23+
#if swift(>=5.7)
24+
/// Describes an entity which be bound towards.
25+
public protocol BindingTargetProvider<Value> {
26+
associatedtype Value
27+
28+
var bindingTarget: BindingTarget<Value> { get }
29+
}
30+
#else
31+
/// Describes an entity which be bound towards.
1932
public protocol BindingTargetProvider {
2033
associatedtype Value
2134

2235
var bindingTarget: BindingTarget<Value> { get }
2336
}
37+
#endif
2438

2539
extension BindingTargetProvider {
2640
/// Binds a source to a target, updating the target's value to the latest
@@ -46,7 +60,7 @@ extension BindingTargetProvider {
4660
/// ````
4761
///
4862
/// - parameters:
49-
/// - target: A target to be bond to.
63+
/// - target: A target to be bound to.
5064
/// - source: A source to bind.
5165
///
5266
/// - returns: A disposable that can be used to terminate binding before the
@@ -86,7 +100,7 @@ extension BindingTargetProvider {
86100
/// ````
87101
///
88102
/// - parameters:
89-
/// - target: A target to be bond to.
103+
/// - target: A target to be bound to.
90104
/// - source: A source to bind.
91105
///
92106
/// - returns: A disposable that can be used to terminate binding before the
@@ -111,7 +125,7 @@ extension Signal.Observer {
111125
/// deinitialized, or when the source sends a `completed` event.
112126
///
113127
/// - parameters:
114-
/// - target: A target to be bond to.
128+
/// - target: A target to be bound to.
115129
/// - source: A source to bind.
116130
///
117131
/// - returns: A disposable that can be used to terminate binding before the

0 commit comments

Comments
 (0)