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
100
use std::ops::{Deref, DerefMut};

use redis::{FromRedisValue, RedisResult, ToRedisArgs};

use crate::{Cmd, ConnectionWrapper};

/// Wrapper for `redis::Cmd` which makes it compatible with the `query_async`
/// method which takes a `ConnectionLike` as argument.
///
/// This Implementation could be simplified a lot via
/// [RFC 2393](https://github.com/rust-lang/rfcs/pull/2393).
///
/// See [redis::Pipeline](https://docs.rs/redis/latest/redis/struct.Pipeline.html)
pub struct Pipeline {
    pipeline: redis::Pipeline,
}

impl Pipeline {
    /// See [redis::Pipeline::new](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.new)
    pub fn new() -> Self {
        Self {
            pipeline: redis::Pipeline::new(),
        }
    }
    /// See [redis::Pipeline::with_capacity](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.with_capacity)
    pub fn with_capacity(capacity: usize) -> Pipeline {
        Self {
            pipeline: redis::Pipeline::with_capacity(capacity),
        }
    }
    /// See [redis::Pipeline::cmd](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.cmd)
    pub fn cmd(&mut self, name: &str) -> &mut Pipeline {
        self.pipeline.cmd(name);
        self
    }
    /// See [redis::Pipeline::add_command](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.add_command)
    pub fn add_command(&mut self, cmd: Cmd) -> &mut Pipeline {
        self.pipeline.add_command(cmd.cmd);
        self
    }
    /// See [redis::Pipeline::arg](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.arg)
    pub fn arg<T: ToRedisArgs>(&mut self, arg: T) -> &mut Pipeline {
        self.pipeline.arg(arg);
        self
    }
    /// See [redis::Pipeline::ignore](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.ignore)
    pub fn ignore(&mut self) -> &mut Pipeline {
        self.pipeline.ignore();
        self
    }
    /// See [redis::Pipeline::atomic](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.atomic)
    pub fn atomic(&mut self) -> &mut Pipeline {
        self.pipeline.atomic();
        self
    }
    /// See [redis::Pipeline::query_async](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.query_async)
    pub async fn query_async<T: FromRedisValue>(
        &self,
        con: &mut ConnectionWrapper,
    ) -> RedisResult<T> {
        self.pipeline.query_async(DerefMut::deref_mut(con)).await
    }
    /// See [redis::Pipeline::execute_async](https://docs.rs/redis/latest/redis/struct.Pipeline.html#method.execute_async)
    pub async fn execute_async(&self, con: &mut ConnectionWrapper) -> RedisResult<()> {
        self.query_async::<redis::Value>(con).await?;
        Ok(())
    }
}

impl Deref for Pipeline {
    type Target = redis::Pipeline;
    fn deref(&self) -> &redis::Pipeline {
        &self.pipeline
    }
}

impl DerefMut for Pipeline {
    fn deref_mut(&mut self) -> &mut redis::Pipeline {
        &mut self.pipeline
    }
}

impl From<redis::Pipeline> for Pipeline {
    fn from(pipeline: redis::Pipeline) -> Self {
        Pipeline { pipeline }
    }
}

impl Into<redis::Pipeline> for Pipeline {
    fn into(self) -> redis::Pipeline {
        self.pipeline
    }
}

/// Shortcut for creating a new pipeline.
///
/// See [redis::pipe](https://docs.rs/redis/latest/redis/fn.pipe.html)
pub fn pipe() -> Pipeline {
    Pipeline::new()
}