Skip to content

Commit 30e15de

Browse files
committed
feat(Configurator): Scope methods
1 parent 5846cf0 commit 30e15de

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

Sources/FunctionalBuilder/Builder.swift

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,43 @@ extension Builder {
126126
)
127127
}
128128

129-
public func callAsFunction(if condition: Bool, _ value: @escaping @autoclosure () -> Value) -> Builder {
129+
public func callAsFunction(
130+
if condition: Bool, then thenValue: @escaping @autoclosure () -> Value
131+
) -> Builder {
130132
Builder(
131133
_block.builder._initialValue,
132134
_block.builder._configurator.appendingConfiguration { base in
133135
if condition {
134-
return _block.keyPath.embed(value(), in: base)
136+
return _block.keyPath.embed(thenValue(), in: base)
137+
} else {
138+
return base
139+
}
140+
}
141+
)
142+
}
143+
144+
public func scope(_ builder: @escaping (Builder<Value>) -> Builder<Value>) -> Builder {
145+
Builder(
146+
_block.builder._initialValue,
147+
_block.builder._configurator.appendingConfiguration { base in
148+
_block.keyPath.embed(
149+
builder(.init(_block.keyPath.extract(from: base))).build(),
150+
in: base)
151+
}
152+
)
153+
}
154+
155+
public func callAsFunction(
156+
if condition: Bool, then thenValue: @escaping @autoclosure () -> Value,
157+
else elseValue: (() -> Value)? = nil
158+
) -> Builder {
159+
Builder(
160+
_block.builder._initialValue,
161+
_block.builder._configurator.appendingConfiguration { base in
162+
if condition {
163+
return _block.keyPath.embed(thenValue(), in: base)
164+
} else if let value = elseValue?() {
165+
return _block.keyPath.embed(value, in: base)
135166
} else {
136167
return base
137168
}

Tests/DeclarativeConfigurationTests/ConfiguratorTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,26 @@ final class ConfiguratorTests: XCTestCase {
121121
XCTAssertEqual(actual.value, expected.value)
122122
XCTAssertEqual(actual._wrapped.value, expected._wrapped.value)
123123
}
124+
125+
func testScope() {
126+
struct Container: ConfigInitializable, Equatable {
127+
struct Content: Equatable {
128+
var a: Int = 0
129+
var b: Int = 0
130+
var c: Int = 0
131+
}
132+
var content: Content = .init()
133+
}
134+
135+
let expected = Container(content: .init(a: 1, b: 2, c: 3))
136+
let actual = Container { $0
137+
.content.scope { $0
138+
.a(1)
139+
.b(2)
140+
.c(3)
141+
}
142+
}
143+
144+
XCTAssertEqual(actual, expected)
145+
}
124146
}

0 commit comments

Comments
 (0)