Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add conversions into UnsyncBoxBody #537

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

nanoqsh
Copy link

@nanoqsh nanoqsh commented Dec 24, 2024

Motivation

I want to return http bodies of different types, for example from multiple match branches. The easiest way to do this is to box the body like:

use {http_body_util::combinators::UnsyncBoxBody, /**/};

let serve = ServeFile::new(/**/);
let res = match req.uri().path() {
    "s1" => Ok(Response::new(UnsyncBoxBody::new(/**/))),
    "s2" => Ok(Response::new(UnsyncBoxBody::new(/**/))),
    _ => serve
        .oneshot(req)
        .await
        .map(|res| res.map(UnsyncBoxBody::new)),
};

But in the case of the body type from the ServeFile/ServeDir service, I have to box what is already boxed. This requires double allocation and, more critically, double indirection. I would like to avoid these overhead costs.

Solution

My proposal to add a conversion impl into the UnsyncBoxBody type. This eliminates the need for additional boxing:

- .map(|res| res.map(UnsyncBoxBody::new))
+ .map(|res| res.map(UnsyncBoxBody::from))

Alternatives

  • I could use the Either type, but it's not convenient with more than two different types. I could do infinite levels of nesting, but I want a more straightforward solution.
  • I could use the service's fallback method, but I want to resolve routes at a higher level, e.g. preferring a route even if a file with same name exists.
  • If exposing implementation details is undesirable, it could be converted directly to the Pin<Box<dyn Body<Data = D, Error = E> + Send>> type.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant