Prettier macro or builder?

What type of server launch would you choose?
Macro:

launch!( 
    server = HTTP,
    listener = TcpListener::bind("127.0.0.1:80").await?,
    fn_work = work,
    fn_check = check
);

Builder:

Server::new()
    .set_type(HTTP),
    .set_listener(TcpListener::bind("127.0.0.1:80").await?)
    .set_fn_work(work)
    .launch()
    .await;

I'd prefer the builder. Mainly because there is no IDE support in macros, but also because I find macros hard to read. I think that macros are great and very useful, but only should be used if there is no realistic alternative.

9 Likes

Or just a struct:

let options = ServerOptions {
    typ: HTTP,
    listener: TcpListener::bind("127.0.0.1:80").await?,
    work,
    check,
};
Server::launch(options).await;

You can use ..Default::default() to leave other fields at their defaults:

ServerOptions {
    listener: TcpListener::bind("127.0.0.1:80").await?,
    work,
    check,
    // All other fields use the default values defined in
    // impl Default for ServerOptions { ... }
    ..ServerOptions::default()
}
4 Likes

Somewhat related blog post Init Struct Pattern – X Blog – A blog for Xaeroxe, Software Engineer

3 Likes

I’ll probably choose your option, because I think it’s the most beautiful.

1 Like

Thank you very much, the post is really very interesting. I'll keep it as a note)