Skip to content

Commit 3f30e81

Browse files
committed
feat(Builder): Scope support for immutable values of classes
1 parent f1e2b11 commit 3f30e81

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

Sources/FunctionalBuilder/Builder.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,19 @@ extension Builder {
234234
var builder: Builder
235235
var keyPath: FunctionalKeyPath<Base, Value>
236236

237+
public func scope(
238+
_ builder: @escaping (Builder<Value>) -> Builder<Value>
239+
) -> Builder where Value: AnyObject {
240+
Builder(
241+
self.builder._initialValue,
242+
self.builder._configurator.appendingConfiguration { base in
243+
keyPath.embed(
244+
builder(.init(keyPath.extract(from: base))).build(),
245+
in: base)
246+
}
247+
)
248+
}
249+
237250
public subscript<LocalValue>(
238251
dynamicMember keyPath: WritableKeyPath<Value, LocalValue>
239252
) -> CallableBlock<LocalValue> where Value: AnyObject {

Tests/DeclarativeConfigurationTests/BuilderTests.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,38 @@ final class BuilderTests: XCTestCase {
5858
}
5959

6060
func testScope() {
61-
struct Container: BuilderProvider, Equatable {
62-
struct Content: Equatable {
61+
struct Container: BuilderProvider {
62+
class Content {
6363
var a: Int = 0
6464
var b: Int = 0
6565
var c: Int = 0
66+
67+
init() {}
6668
}
67-
var content: Content = .init()
69+
70+
let content: Content = .init()
6871
}
6972

70-
let expected = Container(content: .init(a: 1, b: 2, c: 3))
73+
let expected = Container().builder
74+
.content.a(1)
75+
.content.b(2)
76+
.content.c(3)
77+
.build()
7178
let initial = Container()
72-
let actual = initial.builder
79+
let actual = Container().builder
7380
.content.scope { $0
7481
.a(1)
7582
.b(2)
7683
.c(3)
7784
}.build()
7885

79-
XCTAssertNotEqual(initial, expected)
80-
XCTAssertEqual(actual, expected)
86+
87+
XCTAssertNotEqual(actual.content.a, initial.content.a)
88+
XCTAssertNotEqual(actual.content.b, initial.content.b)
89+
XCTAssertNotEqual(actual.content.c, initial.content.c)
90+
91+
XCTAssertEqual(actual.content.a, expected.content.a)
92+
XCTAssertEqual(actual.content.b, expected.content.b)
93+
XCTAssertEqual(actual.content.c, expected.content.c)
8194
}
8295
}

0 commit comments

Comments
 (0)