I've been playing around with result builders a bit. I was thinking of using ExpressibleByStringLiteral to convert a string literal into MyComponent but got hit by a "Cannot convert value of type MyComponent" error.
Is there something I am missing? It seems like the ExpressibleBy*Literal set of protocols would be a great fit for result builders.
enum MyComponent {
case null
case string(String)
}
@resultBuilder
struct MyBuilder
{
static func buildBlock(_ components: MyComponent...) -> MyComponent {
if let firstComponent = components.first {
return firstComponent
} else {
return .null
}
}
}
extension MyComponent: ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self = .string(value)
}
}
extension MyComponent {
init(@MyBuilder build: () -> MyComponent) {
self = build()
}
}
func testItworks() {
let component = MyComponent {
"A String" // Error: Cannot convert value of type MyComponent
}
}
Yeah, IIRC, the buildBlock transform basically does this:
let component = MyComponent {
"A String" // Error: Cannot convert value of type MyComponent
}
gets turned into:
let component = MyComponent {
let _partialResult1 = buildExpression("A String")
let _block = buildBlock(_partialResult1)
return buildFinalResult(_block)
}
where buildExpression and buildFinalResult may be omitted if the builder in question doesn't implement them. So the type of the components in buildBlock can't directly influence the inference of the individual partial results. You can see that also here: