I am trying to wrap a hierarchy of Java builders in a Kotlin type-safe builder. The hierarchy consists of the following builders (and their targets):
- FigureBuilder (Figure)
- LayoutBuilder (Layout)
- TraceBuilder (Trace)
In Java, FigureBuilder has one method that takes a Layout, and another that take n traces, using a varargs method called addTraces():
addTraces(Trace... traces)
The assembly process in Java is basically
Figure f = Figure.builder()
.layout(
Layout.builder()
.title("title")
.build())
.addTraces(
ScatterTrace.builder()
.name("my series")
.build())
.build();
In Kotlin, I have code that creates the figure builder and the layout builder, but I am stuck on the trace builder. My code so far looks like this:
val figure = figure {
layout {title("Wins vs BA")}
addTraces(
ScatterTrace.builder(x, y)
.name("Batting avg.").build()
)
}
fun figure(c: FigureBuilder.() -> Unit) : Figure {
val builder = Figure.builder()
c(builder)
return builder.build()
}
fun FigureBuilder.layout(c: Layout.LayoutBuilder.() -> Unit) {
layout(Layout.builder().apply(c).build())
}
// won't compile: ScatterTrace.builder() requires 2 args
fun FigureBuilder.traces(vararg c: ScatterTrace.ScatterBuilder.() -> Unit) {
c.forEach {
val builder = ScatterTrace.builder()
it(builder)
addTraces(builder.build())
}
}
I'm not at all sure the last function will work if I can get it to compile, but the immediate blocking issue is that ScatterTrace.builder() takes two arguments and I cannot figure out how to pass them into the lambda.
Thanks very much