serde_amqp 0.13.1

A serde implementation of AMQP1.0 protocol.
Documentation
use std::{
    marker::PhantomData,
    ops::{Deref, DerefMut},
};

use serde::{
    de::{self, VariantAccess},
    ser,
};

use crate::{__constants::ARRAY, format_code::EncodingCodes};

/// A sequence of values of a single type.
///
/// encoding name = "array8", encoding code = 0xe0
/// category = array, width = 1,
/// label="up to 2^8 - 1 array elements with total size less than 2^8 octets"
///
/// encoding name = "array32", encoding code = 0xf0,
/// category = array, width = 4
/// label="up to 2^32 - 1 array elements with total size less than 2^32 octets"
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Array<T>(pub Vec<T>);

impl<T> From<Vec<T>> for Array<T> {
    fn from(val: Vec<T>) -> Self {
        Self(val)
    }
}

impl<T> From<Array<T>> for Vec<T> {
    fn from(val: Array<T>) -> Self {
        val.0
    }
}

impl<T> AsMut<Vec<T>> for Array<T> {
    fn as_mut(&mut self) -> &mut Vec<T> {
        &mut self.0
    }
}

impl<T> Deref for Array<T> {
    type Target = Vec<T>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T> DerefMut for Array<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<T> Array<T> {
    /// Consumes the wrapper into the inner vector
    pub fn into_inner(self) -> Vec<T> {
        self.0
    }
}

impl<T: ser::Serialize> ser::Serialize for Array<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_newtype_struct(ARRAY, &self.0)
    }
}

impl<T> IntoIterator for Array<T> {
    type Item = T;

    type IntoIter = std::vec::IntoIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl<'a, T> IntoIterator for &'a Array<T> {
    type Item = &'a T;

    type IntoIter = std::slice::Iter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.iter()
    }
}

impl<'a, T> IntoIterator for &'a mut Array<T> {
    type Item = &'a mut T;

    type IntoIter = std::slice::IterMut<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.iter_mut()
    }
}

impl<T> FromIterator<T> for Array<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        let v = Vec::from_iter(iter);
        Self(v)
    }
}

enum Field {
    Single,
    Multiple,
}

struct FieldVisitor {}

impl<'de> de::Visitor<'de> for FieldVisitor {
    type Value = Field;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("Single or Multiple identifier for Array")
    }

    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        match v
            .try_into()
            .map_err(|_| de::Error::custom("Unable to convert to EncodingCodes"))?
        {
            EncodingCodes::Array8 | EncodingCodes::Array32 => Ok(Field::Multiple),
            _ => Ok(Field::Single),
        }
    }
}

impl<'de> de::Deserialize<'de> for Field {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_identifier(FieldVisitor {})
    }
}

struct Visitor<T> {
    marker: PhantomData<T>,
}

impl<'de, T: de::Deserialize<'de>> de::Visitor<'de> for Visitor<T> {
    type Value = Array<T>;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("struct Array")
    }

    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
    where
        A: de::EnumAccess<'de>,
    {
        let (val, de) = data.variant()?;
        match val {
            Field::Single => {
                let val: T = de.newtype_variant()?;
                Ok(Array(vec![val]))
            }
            Field::Multiple => {
                let vec: Vec<T> = de.newtype_variant()?;
                Ok(Array(vec))
            }
        }
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: de::SeqAccess<'de>,
    {
        let mut vec = Vec::new();
        while let Some(elem) = seq.next_element()? {
            vec.push(elem);
        }
        Ok(Array::from(vec))
    }

    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let vec: Vec<T> = de::Deserialize::deserialize(deserializer)?;
        Ok(Array::from(vec))
    }
}

impl<'de, T: de::Deserialize<'de>> de::Deserialize<'de> for Array<T> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        const VARIANTS: &[&str] = &["Single", "Multiple"];

        #[cfg(not(feature = "json"))]
        {
            deserializer.deserialize_enum(
                ARRAY,
                VARIANTS,
                Visitor {
                    marker: PhantomData,
                },
            )
        }

        #[cfg(feature = "json")]
        {
            if deserializer.is_human_readable() {
                deserializer.deserialize_newtype_struct(
                    ARRAY,
                    Visitor {
                        marker: PhantomData,
                    },
                )
            } else {
                deserializer.deserialize_enum(
                    ARRAY,
                    VARIANTS,
                    Visitor {
                        marker: PhantomData,
                    },
                )
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::{from_slice, to_vec};

    use super::Array;

    #[test]
    fn test_serialize_and_deserialize_multiple_elem_array() {
        let expected = Array(vec![1i32, 2, 3]);
        let buf = to_vec(&expected).unwrap();
        let array: Array<i32> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);

        let expected = Array(vec![
            String::from("abc"),
            String::from("def"),
            String::from("ghi"),
        ]);
        let buf = to_vec(&expected).unwrap();
        let array: Array<String> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);
    }

    #[test]
    fn test_serialize_and_deserialize_array_encoded_single_elem_array() {
        let expected = Array(vec![1i32]);
        let buf = to_vec(&expected).unwrap();
        let array: Array<i32> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);

        let expected = Array(vec![String::from("abc")]);
        let buf = to_vec(&expected).unwrap();
        let array: Array<String> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);
    }

    #[test]
    fn test_serialize_and_deserialize_single_value_encoded_single_elem_array() {
        let value = 1i32;
        let expected = Array(vec![value]);
        let buf = to_vec(&value).unwrap();
        let array: Array<i32> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);

        let value = String::from("abc");
        let expected = Array(vec![value.clone()]);
        let buf = to_vec(&value).unwrap();
        let array: Array<String> = from_slice(&buf).unwrap();
        assert_eq!(array, expected);
    }
}