Repository: rwf2/Rocket (language: rust)

Issue:
Implement `PartialEq` for `http::Status` with derive macro
### API Docs to Existing Functionality

https://api.rocket.rs/v0.5/rocket/http/struct.Status

### Problems with Existing Functionality

Status does not implement `PartialEq` via `derive(PartialEq)`, which causes it to lack `StructuralPartialEq`.

It prohibits using status in match:

```rs
match status {
    Status::Unauthorized => { ... },
    Status::NotFound => { ... },
    _ => { ... }
}
```

because `Status::Unauthorized` is a constant which triggers error:

```
error: to use a constant of type `rocket::http::Status` in a pattern, `rocket::http::Status` must be annotated with `#[derive(PartialEq)]`
  --> my_project/src/errors.rs:40:13
   |
40 |             Status::Unauthorized => { ... },
   |             ^^^^^^^^^^^^^^^^^^^^
   |
   = note: the traits must be derived, manual `impl`s are not sufficient
   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
``` 

### Suggested Changes

I've looked at current implementation of `PartialEq` for `Status`:
https://github.com/rwf2/Rocket/blob/1a3ef5b23fdf4a4619fa9b5d3f24cff6f8008085/core/http/src/status.rs#L363C1-L367C2

And it seems that there is nothing prohibiting automatic derive. 

### Alternatives Considered

An alternative solution to my `match` expression is something like this:

```rs
match status {
    status if status == Status::Unauthorized => { ... },
    status if status == Status::TooManyRequests => { ... },
}
```

But it doesn't feel idiomatic. 

Another would be to use code directly:

```rs
match status.code {
    401 => { ... },
    429 => { ... }
}
```

But here I'm more prone to the typo than using existing constant.

### Additional Context

_No response_

### System Checks

- [X] I do not believe that this suggestion can or should be implemented outside of Rocket.

- [X] I was unable to find a previous suggestion for this change.
Implement `PartialEq` for `http::Status` with derive macro
### API Docs to Existing Functionality

https://api.rocket.rs/v0.5/rocket/http/struct.Status

### Problems with Existing Functionality

Status does not implement `PartialEq` via `derive(PartialEq)`, which causes it to lack `StructuralPartialEq`.

It prohibits using status in match:

```rs
match status {
    Status::Unauthorized => { ... },
    Status::NotFound => { ... },
    _ => { ... }
}
```

because `Status::Unauthorized` is a constant which triggers error:

```
error: to use a constant of type `rocket::http::Status` in a pattern, `rocket::http::Status` must be annotated with `#[derive(PartialEq)]`
  --> my_project/src/errors.rs:40:13
   |
40 |             Status::Unauthorized => { ... },
   |             ^^^^^^^^^^^^^^^^^^^^
   |
   = note: the traits must be derived, manual `impl`s are not sufficient
   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
``` 

### Suggested Changes

I've looked at current implementation of `PartialEq` for `Status`:
https://github.com/rwf2/Rocket/blob/1a3ef5b23fdf4a4619fa9b5d3f24cff6f8008085/core/http/src/status.rs#L363C1-L367C2

And it seems that there is nothing prohibiting automatic derive. 

### Alternatives Considered

An alternative solution to my `match` expression is something like this:

```rs
match status {
    status if status == Status::Unauthorized => { ... },
    status if status == Status::TooManyRequests => { ... },
}
```

But it doesn't feel idiomatic. 

Another would be to use code directly:

```rs
match status.code {
    401 => { ... },
    429 => { ... }
}
```

But here I'm more prone to the typo than using existing constant.

### Additional Context

_No response_

### System Checks

- [X] I do not believe that this suggestion can or should be implemented outside of Rocket.

- [X] I was unable to find a previous suggestion for this change.


Discussion / hints:
Yes, we should do this. This is an artifact of `Status` originally having had a second "reason" field, which prevented using the derives. This field was later removed. If you could submit a PR, that would be helpful.
As an addendum, we should also derive `Eq`, `PartialOrd` and `Ord`, for the same reason.
I'm eager to do the PR, should I also include `Hash`? It also seems to be a good candidate for derive.
Yeah, might as well.
Yes, we should do this. This is an artifact of `Status` originally having had a second "reason" field, which prevented using the derives. This field was later removed. If you could submit a PR, that would be helpful.
As an addendum, we should also derive `Eq`, `PartialOrd` and `Ord`, for the same reason.
I'm eager to do the PR, should I also include `Hash`? It also seems to be a good candidate for derive.
Yeah, might as well.

Fix patch:
diff --git a/core/http/src/status.rs b/core/http/src/status.rs
index f90e40f240..1aa882f438 100644
--- a/core/http/src/status.rs
+++ b/core/http/src/status.rs
@@ -112,7 +112,7 @@ impl StatusClass {
 /// }
 /// # }
 /// ```
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Status {
     /// The HTTP status code associated with this status.
     pub code: u16,
@@ -354,32 +354,6 @@ impl fmt::Display for Status {
     }
 }
 
-impl std::hash::Hash for Status {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.code.hash(state)
-    }
-}
-
-impl PartialEq for Status {
-    fn eq(&self, other: &Self) -> bool {
-        self.code.eq(&other.code)
-    }
-}
-
-impl Eq for Status { }
-
-impl PartialOrd for Status {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl Ord for Status {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        self.code.cmp(&other.code)
-    }
-}
-
 #[cfg(feature = "serde")]
 mod serde_impl {
     use super::*;


Test patch: