Merge pull request #77 from telebofr/add_ignore_error_policies

Add `Ignore` and `IgnoreSafe` error policies.
This commit is contained in:
Temirkhan Myrzamadi 2019-11-02 14:32:47 +00:00 committed by GitHub
commit 66cbedae01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 3 deletions

View file

@ -22,3 +22,4 @@ thiserror = "1.0.2"
default = [] default = []
unstable-stream = [] # add streams to public API unstable-stream = [] # add streams to public API
never-type = [] # add never type (`!`) to punlic API

View file

@ -1,7 +1,10 @@
use std::future::Future; use std::{
pin::Pin,
future::Future,
convert::Infallible,
};
use async_trait::async_trait; use async_trait::async_trait;
use std::pin::Pin;
/// Implementors of this trait are treated as error-handlers. /// Implementors of this trait are treated as error-handlers.
#[async_trait] #[async_trait]
@ -11,6 +14,113 @@ pub trait ErrorPolicy<E> {
E: 'async_trait; E: 'async_trait;
} }
/// Error policy that silently ignores all errors
///
/// ## Example
/// ```
/// # #[tokio::main]
/// # async fn main() {
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
/// ErrorPolicy,
/// Ignore,
/// };
///
/// Ignore.handle_error(()).await;
/// Ignore.handle_error(404).await;
/// Ignore.handle_error(String::from("error")).await;
/// # }
/// ```
pub struct Ignore;
#[async_trait]
impl<E> ErrorPolicy<E> for Ignore
where
E: Send,
{
async fn handle_error(&self, _: E)
where
E: 'async_trait
{}
}
/// Error policy that silently ignores all errors that can never happen (e.g.: [`!`] or [`Infallible`])
///
/// ## Examples
/// ```
/// # #[tokio::main]
/// # async fn main() {
/// use std::convert::{TryInto, Infallible};
///
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
/// ErrorPolicy,
/// IgnoreSafe,
/// };
///
/// let result: Result<String, Infallible> = "str".try_into();
/// match result {
/// Ok(string) => println!("{}", string),
/// Err(inf) => IgnoreSafe.handle_error(inf).await,
/// }
///
/// IgnoreSafe.handle_error(return).await; // return type of `return` is `!` (aka never)
/// # }
/// ```
///
/// ```compile_fail
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
/// ErrorPolicy,
/// IgnoreSafe,
/// };
///
/// IgnoreSafe.handle_error(0);
/// ```
///
/// ## Note
/// Never type is not stabilized yet (see [`#35121`]) so all API that uses [`!`]
/// (including `impl ErrorPolicy<!> for IgnoreSafe`) we hide under the
/// `never-type` cargo feature.
///
/// [`!`]: https://doc.rust-lang.org/std/primitive.never.html
/// [`Infallible`]: std::convert::Infallible
/// [`#35121`]: https://github.com/rust-lang/rust/issues/35121
pub struct IgnoreSafe;
#[cfg(feature = "never-type")]
#[async_trait]
impl ErrorPolicy<!> for IgnoreSafe {
async fn handle_error(&self, never: !)
where
!: 'async_trait
{
never
}
}
#[async_trait]
impl ErrorPolicy<Infallible> for IgnoreSafe {
async fn handle_error(&self, inf: Infallible)
where
Infallible: 'async_trait
{
match inf {}
}
}
/// Implementation of `ErrorPolicy` for `async fn`s
///
/// ## Example
/// ```
/// # #[tokio::main]
/// # async fn main() {
/// use telebofr::dispatching::dispatchers::filter::error_policy::ErrorPolicy;
///
/// let closure = |e: i32| async move {
/// eprintln!("Error code{}", e)
/// };
///
/// closure.handle_error(404).await;
/// # }
/// ```
impl<E, F, Fut> ErrorPolicy<E> for F impl<E, F, Fut> ErrorPolicy<E> for F
where where
F: Fn(E) -> Fut + Sync, F: Fn(E) -> Fut + Sync,

View file

@ -1,3 +1,5 @@
#![cfg_attr(feature = "never-type", feature(never_type))]
#[macro_use] #[macro_use]
extern crate derive_more; extern crate derive_more;
#[macro_use] #[macro_use]