context_async/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
//! This lib provide an trait [`Context`] and a [`Timer`] to control async function.
//!
//! ## Example
//!
//! Here is a simple example. We use [`Timer`] to control an async function
//! to finish in 5 seconds.
//!
//! ```rust
//! use std::time;
//! use context_async::{Context, Timer};
//!
//! async fn a_heavy_async_function(a: u8) -> bool {
//! return true;
//! }
//!
//! # tokio_test::block_on(async {
//! let timer = Timer::with_timeout(time::Duration::from_secs(5));
//!
//! let _ = timer.handle(a_heavy_async_function(0)).await;
//!
//! // or:
//!
//! use context_async::With;
//! let _ = a_heavy_async_function(0).with(&timer).await;
//! # });
//! ```
//!
//! [`Timer`] implements [`Context`], you can pass a [`Context`] to your async function:
//!
//! ```rust
//!
//! use std::time;
//! use context_async::{Context, Error, Timer, With};
//!
//! async fn a_heavy_async_function(a: u8) -> bool {
//! return true;
//! }
//!
//! async fn my_function<Ctx: Context>(ctx: Ctx) -> Result<bool, Error> {
//! a_heavy_async_function(0)
//! .with(ctx)
//! .await
//! }
//!
//! # tokio_test::block_on(async {
//! let timer = Timer::with_timeout(time::Duration::from_secs(5));
//! let _ = my_function(&timer).await;
//! # })
//!
//! ```
//!
//! ## Error
//!
//! [`Context`] returns [`Error`], one of [`Error::ContextCancelled`] or [`Error::ContextTimeout`].
//!
//! ## Features
//! - `actix-web-from-request`: implement actix-web::FromRequest for [`Timer`].
//! - `name`: create a name for each [`Context`].
//! - `tracing`: enable `tracing` and do `tracing::trace!(...)` logging.
mod timer;
mod context;
mod error;
mod with;
#[cfg(feature = "name")]
mod name;
pub use timer::*;
pub use context::*;
pub use error::*;
pub use with::*;
#[cfg(feature = "name")]
pub use name::*;
pub use async_trait::async_trait;
#[doc(hidden)]
pub struct TimeChecker(tokio::time::Instant);
impl Default for TimeChecker {
fn default() -> Self {
Self::new()
}
}
impl TimeChecker {
pub fn new() -> Self {
Self(tokio::time::Instant::now())
}
pub fn not_exceed(&self, duration: tokio::time::Duration) -> bool {
let diff = tokio::time::Instant::now() - self.0;
diff < duration
}
}