this post was submitted on 17 Nov 2023
16 points (94.4% liked)
Rust
6130 readers
45 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
I didn't look beyond the main parts of the HTTP moduel, but what I've noticed basically immediately was that your
pub fn start_server(address: &str, request_handler: fn(Request) -> Response) -> io::Result<()>
uses a function pointer parameter.This is overly restrictive.
fn a()->b
only acceptsfn
s, and closures that do not capture their environment (see the book's chapter on closures). In order to accept closures that capture their environment, you could make that function generic:pub fn start_server(address: &str, request_handler: F) -> io::Result<()> where F : Fn(Request)->Response + Clone +'static
.Clone
requirement is necessary, because you need to pass a copy of the handler to each spawned thread.'static
lifetime is needed because you can't guarantee that the thread doesn't outlive the call to start_server.Now, this can be improved further, because Rust offers a tool to guarantee that all threads are joined before run_server returns: Scoped Threads.
'static
requirement unnecessary, because the function that contains them outlives them by definition.Clone
requirement is not needed either, because due to the limited lifetimes, you can take request_handler by reference, and all references areCopy
(which is a subtrait ofClone
).With scoped threads, a version of your function that could be generic over the request_handler could look something like this (I haven't tried to compile this, it might be utterly wrong):
Edit: Sorry for the messed up characters.
&
should of course just be the ampersand character, and<
should just be the less-than character.