use crate::graceful::ShutdownGuard;
use crate::rt::Executor;
use std::fmt;
use std::ops::{Deref, DerefMut};
use tokio::task::JoinHandle;
mod extensions;
#[doc(inline)]
pub use extensions::Extensions;
#[derive(Debug, Clone)]
pub struct RequestContextExt(Extensions);
impl From<Extensions> for RequestContextExt {
fn from(value: Extensions) -> Self {
Self(value)
}
}
impl From<RequestContextExt> for Extensions {
fn from(value: RequestContextExt) -> Self {
value.0
}
}
impl AsRef<Extensions> for RequestContextExt {
fn as_ref(&self) -> &Extensions {
&self.0
}
}
impl AsMut<Extensions> for RequestContextExt {
fn as_mut(&mut self) -> &mut Extensions {
&mut self.0
}
}
impl Deref for RequestContextExt {
type Target = Extensions;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for RequestContextExt {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub struct Context<S> {
state: S,
executor: Executor,
extensions: Extensions,
}
impl<S: fmt::Debug> fmt::Debug for Context<S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Context")
.field("state", &self.state)
.field("executor", &self.executor)
.field("extensions", &self.extensions)
.finish()
}
}
pub struct Parts<S> {
pub state: S,
pub executor: Executor,
pub extensions: Extensions,
}
impl<S: fmt::Debug> fmt::Debug for Parts<S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Parts")
.field("state", &self.state)
.field("executor", &self.executor)
.field("extensions", &self.extensions)
.finish()
}
}
impl Default for Context<()> {
fn default() -> Self {
Self::new((), Executor::default())
}
}
impl<S: Clone> Clone for Context<S> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
executor: self.executor.clone(),
extensions: self.extensions.clone(),
}
}
}
impl<S> Context<S> {
pub fn new(state: S, executor: Executor) -> Self {
Self {
state,
executor,
extensions: Extensions::new(),
}
}
pub fn from_parts(parts: Parts<S>) -> Self {
Self {
state: parts.state,
executor: parts.executor,
extensions: parts.extensions,
}
}
pub fn into_parts(self) -> Parts<S> {
Parts {
state: self.state,
executor: self.executor,
extensions: self.extensions,
}
}
pub fn with_state(state: S) -> Self {
Self::new(state, Executor::default())
}
pub fn state(&self) -> &S {
&self.state
}
pub fn state_mut(&mut self) -> &mut S {
&mut self.state
}
pub fn map_state<F, W>(self, f: F) -> Context<W>
where
F: FnOnce(S) -> W,
{
Context {
state: f(self.state),
executor: self.executor,
extensions: self.extensions,
}
}
pub fn swap_state<W>(self, state: W) -> (Context<W>, S) {
(
Context {
state,
executor: self.executor,
extensions: self.extensions,
},
self.state,
)
}
pub fn clone_map_state<F, W>(&self, f: F) -> Context<W>
where
S: Clone,
F: FnOnce(S) -> W,
{
Context {
state: f(self.state.clone()),
executor: self.executor.clone(),
extensions: self.extensions.clone(),
}
}
pub fn clone_with_state<W>(&self, state: W) -> Context<W> {
Context {
state,
executor: self.executor.clone(),
extensions: self.extensions.clone(),
}
}
pub fn executor(&self) -> &Executor {
&self.executor
}
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
where
F: Future<Output: Send + 'static> + Send + 'static,
{
self.executor.spawn_task(future)
}
pub fn contains<T: Send + Sync + 'static>(&self) -> bool {
self.extensions.contains::<T>()
}
pub fn get<T: Send + Sync + 'static>(&self) -> Option<&T> {
self.extensions.get::<T>()
}
pub fn get_mut<T: Send + Sync + 'static>(&mut self) -> Option<&mut T> {
self.extensions.get_mut::<T>()
}
pub fn get_or_insert_with<T: Clone + Send + Sync + 'static>(
&mut self,
f: impl FnOnce() -> T,
) -> &mut T {
self.extensions.get_or_insert_with(f)
}
pub fn get_or_insert_with_ctx<T: Clone + Send + Sync + 'static>(
&mut self,
f: impl FnOnce(&Self) -> T,
) -> &mut T {
if self.extensions.contains::<T>() {
return self.extensions.get_mut().unwrap();
}
let v = f(self);
self.extensions.insert(v);
self.extensions.get_mut().unwrap()
}
pub fn get_or_try_insert_with_ctx<T: Clone + Send + Sync + 'static, E>(
&mut self,
f: impl FnOnce(&Self) -> Result<T, E>,
) -> Result<&mut T, E> {
if self.extensions.contains::<T>() {
return Ok(self.extensions.get_mut().unwrap());
}
let v = f(self)?;
self.extensions.insert(v);
Ok(self.extensions.get_mut().unwrap())
}
pub fn get_or_insert_from<T, U>(&mut self, src: U) -> &mut T
where
T: Clone + Send + Sync + 'static,
U: Into<T>,
{
self.extensions.get_or_insert_from(src)
}
pub fn get_or_insert<T: Send + Sync + Clone + 'static>(&mut self, fallback: T) -> &mut T {
self.extensions.get_or_insert(fallback)
}
pub fn get_or_insert_default<T: Clone + Default + Send + Sync + 'static>(&mut self) -> &mut T {
self.extensions.get_or_insert_default()
}
pub fn insert<T: Clone + Send + Sync + 'static>(&mut self, extension: T) -> Option<T> {
self.extensions.insert(extension)
}
pub fn maybe_insert<T: Clone + Send + Sync + 'static>(
&mut self,
extension: Option<T>,
) -> Option<T> {
self.extensions.maybe_insert(extension)
}
pub fn extensions(&self) -> &Extensions {
&self.extensions
}
pub fn extensions_mut(&mut self) -> &mut Extensions {
&mut self.extensions
}
pub fn extend(&mut self, extensions: Extensions) {
self.extensions.extend(extensions);
}
pub fn clear(&mut self) {
self.extensions.clear();
}
pub fn remove<T: Clone + Send + Sync + 'static>(&mut self) -> Option<T> {
self.extensions.remove()
}
pub fn guard(&self) -> Option<&ShutdownGuard> {
self.executor.guard()
}
}
impl<S: Clone> Context<S> {
pub fn state_clone(&self) -> S {
self.state.clone()
}
}