Skip to content

Commit 01a2b2b

Browse files
committed
Allow conversions in ResultExt::status
1 parent 4745f44 commit 01a2b2b

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

src/result_ext.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{Error, StatusCode};
2-
use core::convert::Infallible;
2+
use core::convert::{Infallible, TryInto};
33
use std::error::Error as StdError;
44

55
/// Provides the `status` method for `Result`.
@@ -9,46 +9,68 @@ pub trait ResultExt<T, E>: private::Sealed {
99
/// Wrap the error value with an additional status code.
1010
fn status<S>(self, status: S) -> Result<T, Error>
1111
where
12-
S: Into<StatusCode>;
12+
S: TryInto<StatusCode>,
13+
S::Error: std::fmt::Debug;
1314

1415
/// Wrap the error value with an additional status code that is evaluated
1516
/// lazily only once an error does occur.
1617
fn with_status<S, F>(self, f: F) -> Result<T, Error>
1718
where
18-
S: Into<StatusCode>,
19+
S: TryInto<StatusCode>,
20+
S::Error: std::fmt::Debug,
1921
F: FnOnce() -> S;
2022
}
2123

2224
impl<T, E> ResultExt<T, E> for Result<T, E>
2325
where
2426
E: StdError + Send + Sync + 'static,
2527
{
26-
fn status<S>(self, status: S) -> Result<T, Error> where
27-
S: Into<StatusCode> {
28-
self.map_err(|error| Error::new(status.into(), error))
28+
fn status<S>(self, status: S) -> Result<T, Error>
29+
where
30+
S: TryInto<StatusCode>,
31+
S::Error: std::fmt::Debug,
32+
{
33+
self.map_err(|error| {
34+
let status = status.try_into().unwrap();
35+
Error::new(status, error)
36+
})
2937
}
3038

3139
fn with_status<S, F>(self, f: F) -> Result<T, Error>
3240
where
33-
S: Into<StatusCode>,
41+
S: TryInto<StatusCode>,
42+
S::Error: std::fmt::Debug,
3443
F: FnOnce() -> S,
3544
{
36-
self.map_err(|error| Error::new(f().into(), error))
45+
self.map_err(|error| {
46+
let status = f().try_into().unwrap();
47+
Error::new(status, error)
48+
})
3749
}
3850
}
3951

4052
impl<T> ResultExt<T, Infallible> for Option<T> {
41-
fn status<S>(self, status: S) -> Result<T, Error>
42-
where S: Into<StatusCode> {
43-
self.ok_or_else(|| Error::from_str(status.into(), "NoneError"))
53+
fn status<S>(self, status: S) -> Result<T, Error>
54+
where
55+
S: TryInto<StatusCode>,
56+
S::Error: std::fmt::Debug,
57+
{
58+
self.ok_or_else(|| {
59+
let status = status.try_into().unwrap();
60+
Error::from_str(status, "NoneError")
61+
})
4462
}
4563

4664
fn with_status<S, F>(self, f: F) -> Result<T, Error>
4765
where
48-
S: Into<StatusCode>,
66+
S: TryInto<StatusCode>,
67+
S::Error: std::fmt::Debug,
4968
F: FnOnce() -> S,
5069
{
51-
self.ok_or_else(|| Error::from_str(f().into(), "NoneError"))
70+
self.ok_or_else(|| {
71+
let status = f().try_into().unwrap();
72+
Error::from_str(status, "NoneError")
73+
})
5274
}
5375
}
5476

src/status_code.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,8 @@ impl Into<u16> for &StatusCode {
475475
impl std::convert::TryFrom<u16> for StatusCode {
476476
type Error = crate::Error;
477477

478-
fn try_from(value: u16) -> Result<Self, Self::Error> {
479-
match value {
478+
fn try_from(num: u16) -> Result<Self, Self::Error> {
479+
match num {
480480
100 => Ok(StatusCode::Continue),
481481
101 => Ok(StatusCode::SwitchingProtocols),
482482
103 => Ok(StatusCode::EarlyHints),
@@ -530,7 +530,7 @@ impl std::convert::TryFrom<u16> for StatusCode {
530530
506 => Ok(StatusCode::VariantAlsoNegotiates),
531531
510 => Ok(StatusCode::NotExtended),
532532
511 => Ok(StatusCode::NetworkAuthenticationRequired),
533-
_ => unimplemented!(), // TODO: return parser error
533+
_ => crate::bail!("Invalid status code"),
534534
}
535535
}
536536
}

0 commit comments

Comments
 (0)