memcached-async 0.0.2

Asynchronous memcached protocol parser
Documentation
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};

/// Raw command wrapper.
#[derive(Debug, Clone, Copy)]
pub struct Cmd(pub Op);

/// Single key extractor.
#[derive(Debug, Clone)]
pub struct Key(pub Bytes);

/// Multi-key extractor.
#[derive(Debug, Clone)]
pub struct Keys(pub Vec<Bytes>);

/// Value extractor.
#[derive(Debug, Clone)]
pub struct Value(pub Bytes);

/// Flags extractor.
#[derive(Debug, Clone, Copy)]
pub struct Flags(pub u32);

/// Expiration extractor.
#[derive(Debug, Clone, Copy)]
pub struct Exptime(pub i64);

/// CAS extractor.
#[derive(Debug, Clone, Copy)]
pub struct Cas(pub u64);

/// Delta extractor for incr/decr.
#[derive(Debug, Clone, Copy)]
pub struct Delta(pub u64);

/// Meta flags extractor.
#[derive(Debug, Clone)]
pub struct Meta(pub MetaFlags);

/// Protocol extractor.
#[derive(Debug, Clone, Copy)]
pub struct Protocol(pub Proto);

/// Reply mode extractor.
#[derive(Debug, Clone, Copy)]
pub struct Reply(pub ReplyMode);

/// Opaque token extractor.
#[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())
    }
}