rust
53 lines · 8 steps
The builder pattern in Rust
A RequestBuilder accumulates HTTP request settings through chainable methods before producing a finished Request.
Explained by
highlit
1#[derive(Debug, Default)]
2pub struct RequestBuilder {
3 url: String,
4 method: String,
5 headers: Vec<(String, String)>,
6 body: Option<Vec<u8>>,
7 timeout_ms: u64,
8}
9
10impl RequestBuilder {
11 pub fn new(url: impl Into<String>) -> Self {
12 RequestBuilder {
13 url: url.into(),
14 method: "GET".to_string(),
15 timeout_ms: 30_000,
16 ..Default::default()
17 }
18 }
19
20 pub fn method(&mut self, method: impl Into<String>) -> &mut Self {
21 self.method = method.into();
22 self
23 }
24
25 pub fn header(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {
26 self.headers.push((key.into(), value.into()));
27 self
28 }
29
30 pub fn bearer(&mut self, token: &str) -> &mut Self {
31 self.header("Authorization", format!("Bearer {token}"))
32 }
33
34 pub fn json(&mut self, payload: &[u8]) -> &mut Self {
35 self.body = Some(payload.to_vec());
36 self.header("Content-Type", "application/json")
37 }
38
39 pub fn timeout_ms(&mut self, ms: u64) -> &mut Self {
40 self.timeout_ms = ms;
41 self
42 }
43
44 pub fn build(&self) -> Request {
45 Request {
46 url: self.url.clone(),
47 method: self.method.clone(),
48 headers: self.headers.clone(),
49 body: self.body.clone(),
50 timeout_ms: self.timeout_ms,
51 }
52 }
53}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Returning &mut Self from each setter lets callers chain configuration calls fluently.
- 2Accepting impl Into<String> makes an API accept both &str and String without forcing conversions on the caller.
- 3A dedicated build step separates the mutable, half-finished builder from the finalized, cloned result.
Related explainers
rust
use std::collections::HashMap; #[derive(Debug)] pub struct RequestHead {
Parsing an HTTP request head in Rust
parsing
error-handling
iterators
Intermediate
9 steps
java
package com.example.lb; import java.util.List; import java.util.concurrent.atomic.AtomicInteger;
A thread-safe round-robin load balancer in Java
concurrency
load-balancing
round-robin
Intermediate
9 steps
rust
use axum::{extract::{Path, State}, http::StatusCode, Json}; use dashmap::DashMap; use serde::Serialize; use std::sync::Arc;
Request coalescing in an Axum handler
caching
concurrency
request-coalescing
Advanced
8 steps
rust
use std::net::Ipv4Addr; use std::str::FromStr; #[derive(Debug, Clone, Copy)]
Parsing and matching IPv4 CIDR ranges in Rust
bitwise-operations
parsing
error-handling
Intermediate
8 steps
typescript
type CsvColumn<T> = { header: string; value: (row: T) => string | number | boolean | null | undefined; };
Building a type-safe CSV writer in TypeScript
generics
serialization
escaping
Intermediate
7 steps
java
@RestController @RequestMapping("/api/products") public class ProductSearchController {
Binding collection query params in Spring
rest-api
query-parameters
dependency-injection
Intermediate
6 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/the-builder-pattern-in-rust-explained-rust-e649/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.