Hi Rustaceans,
I wanted to share assemblist, a library I created to simplify immutable builder patterns in Rust. I know the ecosystem already offers many builder-related crates, but I wanted to explore a different approach ā one that makes defining method chains feel more natural and intuitive.
Unlike traditional builders tied to struct annotations, macro assemblist!
lets you declare method chains as you use them, making APIs clearer and more flexible.
Example Usage
Here's a simple example demonstrating the idea:
assemblist!{
fn define_movie<'a>(name: &'a str)
.released_in(release_year: usize)
.directed_by(director_name: &'a str) -> Movie
{
Movie {
name: name.to_string(),
release_year,
director_name: director_name.to_string(),
}
}
}
Once declared, method chains can be called fluently:
let movie = define_movie("The Lobster")
.released_in(2015)
.directed_by("Yorgos Lanthimos");
Supporting Alternative Paths
Assemblist also introduces alternative blocks, allowing users to define multiple possible continuations for a chain using a .{ ⦠}
scope. This mechanism is recursive, enabling expressive branching.
assemblist!{
fn new_http_request_to(url: Uri)
.from<'a>(user_agent: &'a str)
.with_authorization(authorization: HttpAuthorization).{
fn as_get() -> GetHttpRequest {
GetHttpRequest {
url,
user_agent: user_agent.to_string(),
authorization,
}
}
fn as_post().{
fn with_text(body: String) -> PostHttpRequest {
PostHttpRequest {
url,
user_agent: user_agent.to_string(),
authorization,
body: HttpBody::Text(body),
}
}
fn with_json(json: JsonValue) -> PostHttpRequest {
PostHttpRequest {
url,
user_agent: user_agent.to_string(),
authorization,
body: HttpBody::Json(json),
}
}
}
}
}
Looking for Feedback
Assemblist is available on crate.io, and Iād love to hear your thoughts.