use crate::http;
use async_std::sync::{Arc, Mutex, RwLock};
use async_trait::async_trait;
use futures::future::BoxFuture;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Method {
Http(http::Method),
Socket,
Metrics,
}
impl Method {
pub fn get() -> Self {
Self::Http(http::Method::Get)
}
pub fn post() -> Self {
Self::Http(http::Method::Post)
}
pub fn put() -> Self {
Self::Http(http::Method::Put)
}
pub fn delete() -> Self {
Self::Http(http::Method::Delete)
}
pub fn socket() -> Self {
Self::Socket
}
pub fn metrics() -> Self {
Self::Metrics
}
pub fn is_http(&self) -> bool {
matches!(self, Self::Http(_))
}
pub fn is_mutable(&self) -> bool {
match self {
Self::Http(m) => !m.is_safe(),
Self::Socket => true,
Self::Metrics => false,
}
}
}
impl From<http::Method> for Method {
fn from(m: http::Method) -> Self {
Self::Http(m)
}
}
impl Display for Method {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Http(m) => write!(f, "{}", m),
Self::Socket => write!(f, "SOCKET"),
Self::Metrics => write!(f, "METRICS"),
}
}
}
pub struct ParseMethodError;
impl FromStr for Method {
type Err = ParseMethodError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SOCKET" => Ok(Self::Socket),
"METRICS" => Ok(Self::Metrics),
_ => s.parse().map_err(|_| ParseMethodError).map(Self::Http),
}
}
}
#[async_trait]
pub trait ReadState {
type State: 'static;
async fn read<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T;
}
#[async_trait]
pub trait WriteState: ReadState {
async fn write<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a mut Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T;
}
#[async_trait]
impl<State: 'static + Send + Sync> ReadState for RwLock<State> {
type State = State;
async fn read<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&*self.read().await).await
}
}
#[async_trait]
impl<State: 'static + Send + Sync> WriteState for RwLock<State> {
async fn write<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a mut Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&mut *self.write().await).await
}
}
#[async_trait]
impl<State: 'static + Send + Sync> ReadState for Mutex<State> {
type State = State;
async fn read<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&*self.lock().await).await
}
}
#[async_trait]
impl<State: 'static + Send + Sync> WriteState for Mutex<State> {
async fn write<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a mut Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&mut *self.lock().await).await
}
}
#[async_trait]
impl<R: Send + Sync + ReadState> ReadState for Arc<R> {
type State = R::State;
async fn read<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
(**self).read(op).await
}
}
#[async_trait]
impl<W: Send + Sync + WriteState> WriteState for Arc<W> {
async fn write<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a mut Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
(**self).write(op).await
}
}
#[async_trait]
impl ReadState for () {
type State = ();
async fn read<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&()).await
}
}
#[async_trait]
impl WriteState for () {
async fn write<T>(
&self,
op: impl Send + for<'a> FnOnce(&'a mut Self::State) -> BoxFuture<'a, T> + 'async_trait,
) -> T {
op(&mut ()).await
}
}