Closed simpkins closed 6 months ago
I would probably prefer an Other variant on the Status enum to avoid having two apis to convey the same information.
I would probably prefer an Other variant on the Status enum to avoid having two apis to convey the same information.
Sure, I can do that instead if you prefer. I agree that it does make the API a bit nicer. That said, it does have some downsides since it breaks backwards compatibility, and makes the Status
enum take more space to store and no longer convertible to u16 with the as u16
syntax. It also results in slightly weird comparison behavior (e.g., should Status::Ok
and Status::Other(200)
be treated as equal?).
Yes, that can lead to subtle bugs, as every addition of a known status variant is effectively a breaking change. This is actually the reason why I have not already made the change:) @lulf what do you think?
The thing is that we will have a breaking change every time that a new known status code is added. Consider this code:
if let Other(status) = response.status && status == 123
. That code could suddenly fail if 123
is later added as a known status code.
Another option would be to simply expose a status: u16
on the response replacing the current status: Status
enum, and then have a get_status(): Status
function that could try and convert the status: u16
to the known variants in Status
. That would not cause any breaking changes later if we let the Unknown
variant stay instead of introducing an Other(u16)
.
The thing is that we will have a breaking change every time that a new known status code is added. Consider this code:
if let Other(status) = response.status && status == 123
. That code could suddenly fail if123
is later added as a known status code.Another option would be to simply expose a
status: u16
on the response replacing the currentstatus: Status
enum, and then have aget_status(): Status
function that could try and convert thestatus: u16
to the known variants inStatus
. That would not cause any breaking changes later if we let theUnknown
variant stay instead of introducing anOther(u16)
.The thing is that we will have a breaking change every time that a new known status code is added. Consider this code:
if let Other(status) = response.status && status == 123
. That code could suddenly fail if123
is later added as a known status code.Another option would be to simply expose a
status: u16
on the response replacing the currentstatus: Status
enum, and then have aget_status(): Status
function that could try and convert thestatus: u16
to the known variants inStatus
. That would not cause any breaking changes later if we let theUnknown
variant stay instead of introducing anOther(u16)
.
Sorry for being unclear, I think we agree. This is what I meant in my previous comment as well, through a newtype StatusCode (u16) instead of u16. But using u16 directly is perhaps better. Having an get_status() to attempt the conversion makes sense :+1:
Ahh yes! StatusCode(u16)
is a good idea, I like it! We can have that together with a get_status(): Status
on the response where we keep the Status:Unknown
variant. That should not break anything going forward. We could also implement Into<Status> for StatusCode
and TryFrom<StatusCode> for Status
for. @simpkins does this make sense? Sorry for the confusion here. Feel free to make this, the pr is already approved:)
Sure, I can make those changes.
We could also implement
Into<Status> for StatusCode
andTryFrom<StatusCode> for Status
Did you perhaps mean TryFrom<Status> for StatusCode
and From<StatusCode> for Status
?
I did initially take a stab at providing TryFrom<StatusCode> for Status
rather than From<StatusCode>
, but this makes the upgrade process more awkward for downstream code, since they can't just say response.status.into()
to upgrade existing sites expecting a Status
enum.
Looks perfect, thank you! I think that you can merge yourself when you are ready.
Looks perfect, thank you! I think that you can merge yourself when you are ready.
Thanks. It looks like the CI actions are stuck somehow though, so I don't think I can merge it yet. It's reporting the CI / ci (pull_request)
action as still queued. The most recent run succeeded, but I wonder if it is somehow still waiting on this old one?
I re-ran the action, seemed to do the trick!
The
Status
enum only supports a portion of the response codes defined by RFC 9110. If the server returned a response code other than one of the ones supported by theStatus
enum, the code previously threw away the value. This updates the code to also store the code as an integer, so that users can handle other values.I considered simply changing the
Unknown
variant to useUnknown(u16)
, but avoided it for now since this would break backwards compatibility, and would also prevent usingstatus as u16
to convertStatus
values to integers.