use std::convert::Infallible;
use std::sync::Arc;
use bytes::Bytes;
use crate::context::RequestContext;
pub use crate::context::{ClientId, Extensions, LocalAddr, PeerAddr, State};
use crate::error::Error;
use crate::router::FromRequest;
use crate::types::{MetaFlags, Op, Protocol as Proto, ReplyMode, Request};
#[derive(Debug, Clone, Copy)]
pub struct Cmd(pub Op);
#[derive(Debug, Clone)]
pub struct Key(pub Bytes);
#[derive(Debug, Clone)]
pub struct Keys(pub Vec<Bytes>);
#[derive(Debug, Clone)]
pub struct Value(pub Bytes);
#[derive(Debug, Clone, Copy)]
pub struct Flags(pub u32);
#[derive(Debug, Clone, Copy)]
pub struct Exptime(pub i64);
#[derive(Debug, Clone, Copy)]
pub struct Cas(pub u64);
#[derive(Debug, Clone, Copy)]
pub struct Delta(pub u64);
#[derive(Debug, Clone)]
pub struct Meta(pub MetaFlags);
#[derive(Debug, Clone, Copy)]
pub struct Protocol(pub Proto);
#[derive(Debug, Clone, Copy)]
pub struct Reply(pub ReplyMode);
#[derive(Debug, Clone, Copy)]
pub struct Opaque(pub u32);
impl<StateT> FromRequest<StateT> for Cmd
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(Cmd(ctx.request.op))
}
}
impl<StateT> FromRequest<StateT> for Op
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(ctx.request.op)
}
}
impl<StateT> FromRequest<StateT> for Request
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(ctx.request.clone())
}
}
impl<StateT> FromRequest<StateT> for Key
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
if let Some(key) = ctx.request.key.as_ref() {
return Ok(Key(key.clone()));
}
if ctx.request.keys.len() == 1 {
return Ok(Key(ctx.request.keys[0].clone()));
}
Err(Error::client("missing key"))
}
}
impl<StateT> FromRequest<StateT> for Keys
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
if !ctx.request.keys.is_empty() {
return Ok(Keys(ctx.request.keys.clone()));
}
if let Some(key) = ctx.request.key.as_ref() {
return Ok(Keys(vec![key.clone()]));
}
Err(Error::client("missing keys"))
}
}
impl<StateT> FromRequest<StateT> for Value
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.value
.as_ref()
.map(|value| Value(value.clone()))
.ok_or_else(|| Error::client("missing value"))
}
}
impl<StateT> FromRequest<StateT> for Flags
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.flags
.map(Flags)
.ok_or_else(|| Error::client("missing flags"))
}
}
impl<StateT> FromRequest<StateT> for Exptime
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.exptime
.map(Exptime)
.ok_or_else(|| Error::client("missing exptime"))
}
}
impl<StateT> FromRequest<StateT> for Cas
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.cas
.map(Cas)
.ok_or_else(|| Error::client("missing cas"))
}
}
impl<StateT> FromRequest<StateT> for Delta
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.delta
.map(Delta)
.ok_or_else(|| Error::client("missing delta"))
}
}
impl<StateT> FromRequest<StateT> for Meta
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.request
.meta
.clone()
.map(Meta)
.ok_or_else(|| Error::client("missing meta flags"))
}
}
impl<StateT> FromRequest<StateT> for Protocol
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(Protocol(ctx.meta.protocol))
}
}
impl<StateT> FromRequest<StateT> for Reply
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(Reply(ctx.meta.reply))
}
}
impl<StateT> FromRequest<StateT> for Opaque
where
StateT: Send + Sync + 'static,
{
type Rejection = Error;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
ctx.meta
.opaque
.map(Opaque)
.ok_or_else(|| Error::client("missing opaque"))
}
}
impl<T> FromRequest<T> for State<T>
where
T: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
_ctx: &mut RequestContext,
state: &Arc<T>,
) -> Result<Self, Self::Rejection> {
Ok(State(Arc::clone(state)))
}
}
impl<StateT> FromRequest<StateT> for PeerAddr
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(PeerAddr(ctx.peer_addr))
}
}
impl<StateT> FromRequest<StateT> for LocalAddr
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(LocalAddr(ctx.local_addr))
}
}
impl<StateT> FromRequest<StateT> for ClientId
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(ClientId(ctx.client_id))
}
}
impl<StateT> FromRequest<StateT> for Extensions
where
StateT: Send + Sync + 'static,
{
type Rejection = Infallible;
async fn from_request(
ctx: &mut RequestContext,
_state: &Arc<StateT>,
) -> Result<Self, Self::Rejection> {
Ok(ctx.extensions.clone())
}
}