rustis 0.7.2

Redis async driver for Rust
Documentation
use smallvec::SmallVec;

use crate::{resp::Command, PushSender, PubSubSender, ValueSender, RetryReason};

#[allow(clippy::large_enum_variant)] 
#[derive(Debug)]
pub(crate) enum Commands {
    None,
    Single(Command),
    Batch(Vec<Command>),
}

impl Commands {
    pub fn len(&self) -> usize {
        match &self {
            Commands::None => 0,
            Commands::Single(_) => 1,
            Commands::Batch(commands) => commands.len(),
        }
    }
}

impl IntoIterator for Commands {
    type Item = Command;
    type IntoIter = CommandsIterator;

    fn into_iter(self) -> Self::IntoIter {
        match self {
            Commands::None => CommandsIterator::Single(None),
            Commands::Single(command) => CommandsIterator::Single(Some(command)),
            Commands::Batch(commands) => CommandsIterator::Batch(commands.into_iter()),
        }
    }
}

impl<'a> IntoIterator for &'a Commands {
    type Item = &'a Command;
    type IntoIter = RefCommandsIterator<'a>;

    fn into_iter(self) -> Self::IntoIter {
        match self {
            Commands::None => RefCommandsIterator::Single(None),
            Commands::Single(command) => RefCommandsIterator::Single(Some(command)),
            Commands::Batch(commands) => RefCommandsIterator::Batch(commands.iter()),
        }
    }
}

impl<'a> IntoIterator for &'a mut Commands {
    type Item = &'a mut Command;
    type IntoIter = CommandsIteratorMut<'a>;

    fn into_iter(self) -> Self::IntoIter {
        match self {
            Commands::None => CommandsIteratorMut::Single(None),
            Commands::Single(command) => CommandsIteratorMut::Single(Some(command)),
            Commands::Batch(commands) => CommandsIteratorMut::Batch(commands.iter_mut()),
        }
    }
}

#[allow(clippy::large_enum_variant)] 
pub enum CommandsIterator {
    Single(Option<Command>),
    Batch(std::vec::IntoIter<Command>),
}

impl Iterator for CommandsIterator {
    type Item = Command;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Self::Single(command) => command.take(),
            Self::Batch(iter) => iter.next(),
        }
    }
}

pub enum RefCommandsIterator<'a> {
    Single(Option<&'a Command>),
    Batch(std::slice::Iter<'a, Command>),
}

impl<'a> Iterator for RefCommandsIterator<'a> {
    type Item = &'a Command;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Self::Single(command) => command.take(),
            Self::Batch(iter) => iter.next(),
        }
    }
}

pub enum CommandsIteratorMut<'a> {
    Single(Option<&'a mut Command>),
    Batch(std::slice::IterMut<'a, Command>),
}

impl<'a> Iterator for CommandsIteratorMut<'a> {
    type Item = &'a mut Command;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Self::Single(command) => command.take(),
            Self::Batch(iter) => iter.next(),
        }
    }
}

#[derive(Debug)]
pub(crate) struct Message {
    pub commands: Commands,
    pub value_sender: Option<ValueSender>,
    pub pub_sub_senders: Option<Vec<(Vec<u8>, PubSubSender)>>,
    pub push_sender: Option<PushSender>,
    pub retry_reasons: Option<SmallVec<[RetryReason; 10]>>,
    pub retry_on_error: bool
}

impl Message {
    #[inline(always)]
    pub fn single(command: Command, value_sender: ValueSender, retry_on_error: bool) -> Self {
        Message {
            commands: Commands::Single(command),
            value_sender: Some(value_sender),
            pub_sub_senders: None,
            push_sender: None,
            retry_reasons: None,
            retry_on_error,
        }
    }

    #[inline(always)]
    pub fn single_forget(command: Command, retry_on_error: bool) -> Self {
        Message {
            commands: Commands::Single(command),
            value_sender: None,
            pub_sub_senders: None,
            push_sender: None,
            retry_reasons: None,
            retry_on_error,
        }
    }

    #[inline(always)]
    pub fn batch(commands: Vec<Command>, value_sender: ValueSender, retry_on_error: bool) -> Self {
        Message {
            commands: Commands::Batch(commands),
            value_sender: Some(value_sender),
            pub_sub_senders: None,
            push_sender: None,
            retry_reasons: None,
            retry_on_error,
        }
    }

    #[inline(always)]
    pub fn pub_sub(
        command: Command,
        value_sender: ValueSender,
        pub_sub_senders: Vec<(Vec<u8>, PubSubSender)>,
    ) -> Self {
        Message {
            commands: Commands::Single(command),
            value_sender: Some(value_sender),
            pub_sub_senders: Some(pub_sub_senders),
            push_sender: None,
            retry_reasons: None,
            retry_on_error: true,
        }
    }

    #[inline(always)]
    pub fn monitor(
        command: Command,
        value_sender: ValueSender,
        push_sender: PushSender,
    ) -> Self {
        Message {
            commands: Commands::Single(command),
            value_sender: Some(value_sender),
            pub_sub_senders: None,
            push_sender: Some(push_sender),
            retry_reasons: None,
            retry_on_error: true,
        }
    }

    #[inline(always)]
    pub fn client_tracking_invalidation(push_sender: PushSender) -> Self {
        Message {
            commands: Commands::None,
            value_sender: None,
            pub_sub_senders: None,
            push_sender: Some(push_sender),
            retry_reasons: None,
            retry_on_error: false,
        }
    }
}