http-body icon indicating copy to clipboard operation
http-body copied to clipboard

Make `Full` and `Empty` generic over the error type

Open davidpdrsn opened this issue 2 years ago • 2 comments

It is not uncommon to have a function that creatures a boxed body via Full or Empty:

fn box_body_from_bytes(bytes: Bytes) -> UnsyncBoxBody<Bytes, Error> {
    Full::new(bytes)
        .map_err(|e| match e {})
        .boxed_unsync()
}

The .map_err(|e| match e {}) dance is necessary because Full always uses Infallible as its error type, so we have to convert that into whatever error type we actually need. This will often be hyper's, tonic's, or axum's error type.

However if we make Full generic over the error type:

pub struct Full<D, E> { ... }

then Rust can just infer it and we avoid having to call map_err:

fn box_body_from_bytes(bytes: Bytes) -> UnsyncBoxBody<Bytes, Error> {
    Full::new(bytes).boxed_unsync()
}

I think this is quite a bit nicer. It is especially nice that we avoid having to type match e {} which is quite confusing unless you've see it before.

The downside to this is that if the error type cannot be infered you have to explicitly set it when creating a Full:

Full::<_, Error>::new(bytes)

That makes this a breaking change.

davidpdrsn avatar Feb 08 '23 11:02 davidpdrsn

I'm in favor of this; it'd make testing of functions that otherwise accept "production" types much more straighforward.

With the addition of the default, would this be a breaking change?

acfoltzer avatar Jun 18 '24 23:06 acfoltzer

I think the default keeps it from being breaking. But it also means simply Full::new(bytes) probably has to require the default, otherwise inference will break, unfortunately.

seanmonstar avatar Jun 19 '24 13:06 seanmonstar