rustis 0.19.3

Redis async driver for Rust
Documentation
use crate::resp::{RespResponse, RespView};
use std::fmt;

pub enum PubSubMessage<'a> {
    Subscribe(&'a [u8]),
    PSubscribe(&'a [u8]),
    SSubscribe(&'a [u8]),
    Unsubscribe(&'a [u8]),
    PUnsubscribe(&'a [u8]),
    SUnsubscribe(&'a [u8]),
    Message(&'a [u8], &'a [u8]),
    PMessage(&'a [u8], &'a [u8], &'a [u8]),
    SMessage(&'a [u8], &'a [u8]),
}

impl<'a> fmt::Debug for PubSubMessage<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Subscribe(arg0) => f
                .debug_tuple("Subscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::PSubscribe(arg0) => f
                .debug_tuple("PSubscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::SSubscribe(arg0) => f
                .debug_tuple("SSubscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::Unsubscribe(arg0) => f
                .debug_tuple("Unsubscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::PUnsubscribe(arg0) => f
                .debug_tuple("PUnsubscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::SUnsubscribe(arg0) => f
                .debug_tuple("SUnsubscribe")
                .field(&String::from_utf8_lossy(arg0))
                .finish(),
            Self::Message(arg0, arg1) => f
                .debug_tuple("Message")
                .field(&String::from_utf8_lossy(arg0))
                .field(&String::from_utf8_lossy(arg1))
                .finish(),
            Self::PMessage(arg0, arg1, arg2) => f
                .debug_tuple("PMessage")
                .field(&String::from_utf8_lossy(arg0))
                .field(&String::from_utf8_lossy(arg1))
                .field(&String::from_utf8_lossy(arg2))
                .finish(),
            Self::SMessage(arg0, arg1) => f
                .debug_tuple("SMessage")
                .field(&String::from_utf8_lossy(arg0))
                .field(&String::from_utf8_lossy(arg1))
                .finish(),
        }
    }
}

impl<'a> TryFrom<&'a RespResponse> for PubSubMessage<'a> {
    type Error = ();

    fn try_from(response: &'a RespResponse) -> Result<Self, Self::Error> {
        if let RespView::Push(resp_array) = response.view() {
            if resp_array.len() < 2 {
                return Err(());
            }

            let mut iterator = resp_array.into_iter();

            let Some(RespView::BulkString(kind)) = iterator.next() else {
                return Err(());
            };

            let Some(RespView::BulkString(channel_or_pattern)) = iterator.next() else {
                return Err(());
            };

            match kind {
                b"subscribe" => Ok(PubSubMessage::Subscribe(channel_or_pattern)),
                b"psubscribe" => Ok(PubSubMessage::PSubscribe(channel_or_pattern)),
                b"ssubscribe" => Ok(PubSubMessage::SSubscribe(channel_or_pattern)),
                b"unsubscribe" => Ok(PubSubMessage::Unsubscribe(channel_or_pattern)),
                b"punsubscribe" => Ok(PubSubMessage::PUnsubscribe(channel_or_pattern)),
                b"sunsubscribe" => Ok(PubSubMessage::SUnsubscribe(channel_or_pattern)),
                b"message" => {
                    let Some(RespView::BulkString(payload)) = iterator.next() else {
                        return Err(());
                    };

                    Ok(PubSubMessage::Message(channel_or_pattern, payload))
                }
                b"pmessage" => {
                    let Some(RespView::BulkString(channel)) = iterator.next() else {
                        return Err(());
                    };

                    let Some(RespView::BulkString(payload)) = iterator.next() else {
                        return Err(());
                    };

                    Ok(PubSubMessage::PMessage(
                        channel_or_pattern,
                        channel,
                        payload,
                    ))
                }
                b"smessage" => {
                    let Some(RespView::BulkString(payload)) = iterator.next() else {
                        return Err(());
                    };
                    Ok(PubSubMessage::SMessage(channel_or_pattern, payload))
                }
                _ => Err(()),
            }
        } else {
            Err(())
        }
    }
}