Why is hyper handling http versions this way?

I've been looking at hyper for some inspiration on how to handle different versions of some protocol/file format (in the case of hyper, http versions) and I was surprised to see how it's done in version.rs.

There's a private Http enum, and then there's a public Version struct that uses an associated constant for each variant of the Http enum. I am wondering what are the benefits of doing things this way vs a simple enum? I looked at associated constants in the Rust reference but it didn't really explain in what situations they're interesting to use.

I guess because adding a variant to a public enum is a breaking change while adding an associated constant to a public type is not. Why they prefer it like that instead of using #[non_exhaustive], I think it is for historic reasons. http's initial commit is from March 2017 while non_exhaustive's RFC is a few months younger, from May 2017.

3 Likes

Oh I see! Thx for the pointer, I didn't think of checking out the commit history... I will keep that in mind in the future :slight_smile:

So I guess if one were to do something similar today they would simply use an enum with #[non_exhaustive] right?

I'd say depends. For an enum of supported HTTP protocols, the ability to match over enum variants may come in handy. Also, there won't be 200 variants in the near future, which is also something I'd consider in my decision of constants vs. enum. The last thing I'd put into consideration would be, if you can have custom variants. Good examples where constants make more sense IMO are mime types and http headers. You could represent them as enums as well, but having them as constants feels somewhat more logical, given that you can define your custom mime types and custom headers, besides the ones that are standardised.

1 Like

Ok, thank you very much for the detailed answer :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.