Consolidate to one Context impl for Result to improve inference

This commit is contained in:
David Tolnay 2019-10-11 18:24:26 -07:00
parent 6057864f8b
commit c695e63286
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -65,15 +65,49 @@ pub trait Context<T, E>: private::Sealed {
F: FnOnce() -> C; F: FnOnce() -> C;
} }
mod ext {
use super::*;
pub trait StdError {
fn ext_context<C>(self, context: C) -> Error
where
C: Display + Send + Sync + 'static;
}
impl<E> StdError for E
where
E: std::error::Error + Send + Sync + 'static,
{
fn ext_context<C>(self, context: C) -> Error
where
C: Display + Send + Sync + 'static,
{
Error::new(ContextError {
error: self,
context,
})
}
}
impl StdError for Error {
fn ext_context<C>(self, context: C) -> Error
where
C: Display + Send + Sync + 'static,
{
self.context(context)
}
}
}
impl<T, E> Context<T, E> for Result<T, E> impl<T, E> Context<T, E> for Result<T, E>
where where
E: StdError + Send + Sync + 'static, E: ext::StdError + Send + Sync + 'static,
{ {
fn context<C>(self, context: C) -> Result<T, Error> fn context<C>(self, context: C) -> Result<T, Error>
where where
C: Display + Send + Sync + 'static, C: Display + Send + Sync + 'static,
{ {
self.map_err(|error| Error::new(ContextError { error, context })) self.map_err(|error| error.ext_context(context))
} }
fn with_context<C, F>(self, context: F) -> Result<T, Error> fn with_context<C, F>(self, context: F) -> Result<T, Error>
@ -81,29 +115,7 @@ where
C: Display + Send + Sync + 'static, C: Display + Send + Sync + 'static,
F: FnOnce() -> C, F: FnOnce() -> C,
{ {
self.map_err(|error| { self.map_err(|error| error.ext_context(context()))
Error::new(ContextError {
error,
context: context(),
})
})
}
}
impl<T> Context<T, Error> for Result<T, Error> {
fn context<C>(self, context: C) -> Result<T, Error>
where
C: Display + Send + Sync + 'static,
{
self.map_err(|error| error.context(context))
}
fn with_context<C, F>(self, context: F) -> Result<T, Error>
where
C: Display + Send + Sync + 'static,
F: FnOnce() -> C,
{
self.map_err(|error| error.context(context()))
} }
} }
@ -198,12 +210,10 @@ where
} }
mod private { mod private {
use crate::Error; use super::*;
use std::error::Error as StdError;
pub trait Sealed {} pub trait Sealed {}
impl<T, E> Sealed for Result<T, E> where E: StdError + Send + Sync + 'static {} impl<T, E> Sealed for Result<T, E> where E: ext::StdError {}
impl<T> Sealed for Result<T, Error> {}
impl<T> Sealed for Option<T> {} impl<T> Sealed for Option<T> {}
} }