Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement Default for HttpBody1ToHttpBody04 #4

Merged
merged 2 commits into from
Mar 13, 2023

Conversation

howardjohn
Copy link
Contributor

see hyperium/tonic#1307

Tonic interceptors require a Default on the body. This makes it easier to use an adapter type tonic.

FWIW the default type I am using:

#[derive(Default)]
pub enum DefaultIncoming {
    Some(Incoming),
    #[default]
    Empty
}

impl Body for DefaultIncoming {
    type Data = Bytes;
    type Error = hyper::Error;

    fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
        match self.get_mut() {
            DefaultIncoming::Some(ref mut i) => Pin::new(i).poll_frame(cx),
            DefaultIncoming::Empty => Pin::new(&mut http_body_util::Empty::<Bytes>::new()).poll_frame(cx).map_err(|_| unreachable!())
        }
    }
}

Copy link
Owner

@davidpdrsn davidpdrsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use #[derive(Default)]?

@howardjohn
Copy link
Contributor Author

howardjohn commented Mar 10, 2023

Can you use #[derive(Default)]?

I don't think so, because we only want to implement Default if B: Default? Or I don't know how to, at least 🙂

@davidpdrsn
Copy link
Owner

I don't think so, because we only want to implement Default if B: Default?

That is how it works. How else could it create a body?

@howardjohn
Copy link
Contributor Author

I don't think so, because we only want to implement Default if B: Default?

That is how it works. How else could it create a body?

Today you can use the adaptor without B: Default though. Derive would mean it MUST be Default, the approach here makes it Default only if the inner type is? In particular, hyper Incoming is not Default so I am not sure we should require it

@davidpdrsn
Copy link
Owner

davidpdrsn commented Mar 11, 2023

I think you're misunderstanding how #[derive(Default)] works. These two things are exactly the same:

#[derive(Default)] // this derive...
pub struct HttpBody1ToHttpBody04<B> {
    body: B,
    trailers: Option<HeaderMap>,
}

// ...is the same as

impl<B: Default> Default for HttpBody1ToHttpBody04<B> {
    fn default() -> Self {
        Self {
            body: B::default(),
            trailers: <Option<HeaderMap>>::default(),
        }
    }
}

It does not add this

#[derive(Default)]
pub struct HttpBody1ToHttpBody04<B: Default> {
                              // ^^^^^^^^^^
    body: B,
    trailers: Option<HeaderMap>,
}

@howardjohn
Copy link
Contributor Author

Oh that is great, thanks for the tip. I wasn't aware the derive was that smart.

@davidpdrsn davidpdrsn changed the title body: add Default impl when underlying type is Default Implement Default for HttpBody1ToHttpBody04 Mar 13, 2023
@davidpdrsn davidpdrsn merged commit db9e00b into davidpdrsn:main Mar 13, 2023
@davidpdrsn
Copy link
Owner

Published in 0.1.3 🎉

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

Successfully merging this pull request may close these issues.

2 participants