A builder keeps optional configuration separate from the final value that callers actually use.

Program

Play the program to choose a timeout and build a request through chained methods.

builder_request_config.rs
struct Request {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

struct RequestBuilder {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

impl RequestBuilder {
    fn new(path: &'static str) -> Self {
        Self { method: "GET", path, timeout: 10 }
    }

    fn timeout(mut self, seconds: u32) -> Self {
        self.timeout = seconds;
        self
    }

    fn build(self) -> Request {
        Request { method: self.method, path: self.path, timeout: self.timeout }
    }
}

fn main() {
    let timeout = ;
    let request = RequestBuilder::new("/v1").timeout(timeout).build();
    println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
struct Request {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

struct RequestBuilder {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

impl RequestBuilder {
    fn new(path: &'static str) -> Self {
        Self { method: "GET", path, timeout: 10 }
    }

    fn timeout(mut self, seconds: u32) -> Self {
        self.timeout = seconds;
        self
    }

    fn build(self) -> Request {
        Request { method: self.method, path: self.path, timeout: self.timeout }
    }
}

fn main() {
    let timeout = ;
    let request = RequestBuilder::new("/v1").timeout(timeout).build();
    println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
struct Request {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

struct RequestBuilder {
    method: &'static str,
    path: &'static str,
    timeout: u32,
}

impl RequestBuilder {
    fn new(path: &'static str) -> Self {
        Self { method: "GET", path, timeout: 10 }
    }

    fn timeout(mut self, seconds: u32) -> Self {
        self.timeout = seconds;
        self
    }

    fn build(self) -> Request {
        Request { method: self.method, path: self.path, timeout: self.timeout }
    }
}

fn main() {
    let timeout = ;
    let request = RequestBuilder::new("/v1").timeout(timeout).build();
    println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
builder A builder stores configuration while the caller chains methods.
by-value methods `timeout` takes and returns `self`, which supports method chaining.
final type `build` creates the finished `Request` value with the selected configuration.