ruvio-client 0.2.8

RESP2 client for the Ruvio key-value server
Documentation
/// One RESP2 value.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RespValue {
    /// A simple string, such as `OK`.
    Simple(String),
    /// An error reply. [`crate::Client::execute`] returns this as [`crate::Error::Server`].
    Error(String),
    /// A signed integer.
    Integer(i64),
    /// A bulk string, including the empty bulk.
    Bulk(Vec<u8>),
    /// An array of values.
    Array(Vec<RespValue>),
    /// A null bulk or a null array.
    Null,
}

impl RespValue {
    /// UTF-8 text of a simple string, error, or bulk string. An integer is its
    /// decimal form. `None` when the value is null or an array (including a
    /// Pub/Sub push).
    pub fn as_string(&self) -> Result<Option<String>, crate::Error> {
        match self {
            RespValue::Null | RespValue::Array(_) => Ok(None),
            RespValue::Integer(value) => Ok(Some(value.to_string())),
            RespValue::Simple(text) | RespValue::Error(text) => Ok(Some(text.clone())),
            RespValue::Bulk(bytes) => {
                let text = String::from_utf8(bytes.clone())
                    .map_err(|_| crate::Error::Protocol("bulk string is not UTF-8".to_owned()))?;

                Ok(Some(text))
            }
        }
    }

    /// The integer, or `None` for any other kind.
    pub fn as_integer(&self) -> Option<i64> {
        match self {
            RespValue::Integer(value) => Some(*value),
            _ => None,
        }
    }

    /// The array items, or `None` for any other kind.
    pub fn as_array(&self) -> Option<&[RespValue]> {
        match self {
            RespValue::Array(items) => Some(items),
            _ => None,
        }
    }

    /// True for a null bulk or a null array.
    pub fn is_null(&self) -> bool {
        matches!(self, RespValue::Null)
    }
}

#[cfg(test)]
mod tests {
    use super::RespValue;

    #[test]
    fn as_string_does_not_fail_on_an_array_or_integer() {
        let message = RespValue::Array(vec![
            RespValue::Bulk(b"message".to_vec()),
            RespValue::Bulk(b"news".to_vec()),
            RespValue::Bulk(b"hello".to_vec()),
        ]);

        assert_eq!(message.as_string().unwrap(), None);
        assert_eq!(
            message.as_array().unwrap()[2]
                .as_string()
                .unwrap()
                .as_deref(),
            Some("hello")
        );
        assert_eq!(
            RespValue::Integer(3).as_string().unwrap().as_deref(),
            Some("3")
        );
    }
}