Rust syntactic patterns for creating a tree of different types?

⚓ Rust    📅 2026-05-11    👤 surdeus    👁️ 1      

surdeus

A few years ago I was writing a lot of Swift and Kotlin code. I liked keyword arguments.

insert(thing: t, after: other_thing, size: .medium)

In Rust, I have found that I can use the builder pattern, for APIs that need it. It's not as easy in some cases as plain keyword arguments, but it provides other cool possibilities, like type state builders. So I don't really miss keyword arguments.

But today I'm missing another syntax from Swift and Kotlin. It's implemented differently in each language, but in the end it lets you write things like:

let widget = VStack {
   Button("OK") { print("clicked") }
   Label("Hello")
   HStack {
       Button("More")
       ...
   }
}

They are sort of like function calls, but if there are trailing braces { ... } that block becomes a closure that is passed as a trailing argument to the function. This lets you build a tree that nicely matches up with the {...} syntax. It is used to create trees of UI widgets in SwiftUI or similar Kotlin APIs. The two languages implement this differently, but I won't elaborate on that here.

My question is: what is a way, or ways, to create trees of objects like this in Rust? Besides brute force mutability, like:

let mut stack = VStack::new();
let mut button = Button::new("OK");
button.add_click_handler(|| println!("Clicked"));
stack.add(button);
stack.add(Label::new("Hello"));
...

Maybe the answer is: macros? Or perhaps trying to create a macro for each widget type will get too ugly.

The Swift version actually creates generic args from the contents of the {...} body, so above it would create a VStack<Button, Label, HStack> or similar.

(Side note: I think they (Swift) paid a pretty high price for this syntax. When I last was working with SwiftUI I could create generic types where the compiler would give up with a message like "I can't finish type-checking that", as opposed to "this code is wrong".)

3 posts - 3 participants

Read full topic

🏷️ Rust_feed