Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upSwitch to &mut self builder #108
Comments
dtolnay
referenced this issue
May 31, 2017
Open
Tracking issue for libz blitz evaluation of reqwest #120
seanmonstar
modified the milestone:
1.0
May 31, 2017
This comment has been minimized.
This comment has been minimized.
|
Adding some more details, an example of how the code could look is: pub struct RequestBuilder {
client: ClientRef,
request: Option<Request>,
}Where impl RequestBuilder {
fn request_mut(&mut self) -> &mut Request {
self.request.as_mut().expect("Builder cannot be reused after building a Request")
}
pub fn json<T: Serialize>(&mut self, val: T) -> reqwest::Result<&mut RequestBuilder> {
let json = serde_json::to_vec(val)?;
self.request_mut().set_body(Body::from(json));
self
}
}There would be 2 public methods on the builder to "consume" it: impl RequestBuilder {
fn take_request(&mut self) -> Request {
self.request.take().expect("Builder cannot be reused after building a Request")
}
pub fn send(&mut self) -> reqwest::Result<Response> {
self.client.send(self.take_request())
}
pub fn build(&mut self) -> Request {
self.take_request()
}
} |
This was referenced May 31, 2017
seanmonstar
closed this
in
e176dce
Jun 1, 2017
This comment has been minimized.
This comment has been minimized.
dtantsur
commented
Dec 29, 2017
|
Sorry for necroposting, but this is a bit an unfortunate decision. I understand why it was made, but it also makes it harder to return RequestBuilder from functions. Imagine (pseudo-rust): fn custom_request(method: Method, url: Url) -> RequestBuilder {
let extra_hdrs = calculate_some_headers();
make_client().request(method, url).headers(extra_hdrs)
}This is what I need to do (custom authentication, if it matters), and as you see it does not work, because headers() returns a mutable reference to a temporary object. What I have to do is roughly this (keeping in mind I have all lints as fatal, including unused_results): fn custom_request(method: Method, url: Url) -> RequestBuilder {
let extra_hdrs = calculate_some_headers();
let builder = make_client().request(method, url);
{
let _unused = builder.headers(extra_hdrs);
}
builder
}If this &mut approach was added to some guidelines, was this problem even considered? |
This comment has been minimized.
This comment has been minimized.
|
Hi @dtantsur! The API guidelines are always open to more insight, we've got an open issue there about |
dtolnay commentedMay 31, 2017
According to the builders API guideline, we like &mut self builders.
The RequestBuilder method signatures should change to &mut self:
Also they should fail fast where applicable:
The state inside the builder should be stored in a way that enables
send(or any other terminal method) to accept &mut self as well but take ownership of the state inside, for example by storingOption<T>from which the terminal method cantake()the value.Any further use of the builder after
sendhas been called should panic, and this behavior should be documented.