cds 0.10.0

Collection of Optimized Data Structures
Documentation
use crate::{
    arraystring::{errors::InsufficientCapacityError, ArrayString},
    len::LengthType,
    mem::SpareMemoryPolicy,
};
use core::{convert::TryFrom, ptr, slice};

impl<L, SM, const C: usize> TryFrom<&str> for ArrayString<C, L, SM>
where
    L: LengthType,
    SM: SpareMemoryPolicy<u8>,
{
    type Error = InsufficientCapacityError;

    #[inline]
    fn try_from(s: &str) -> Result<Self, Self::Error> {
        let len = s.len();
        if len > Self::CAPACITY {
            return Err(InsufficientCapacityError {});
        }
        let mut tmp = Self::new_raw(len);
        unsafe {
            ptr::copy_nonoverlapping(s.as_ptr(), tmp.as_mut_ptr(), len);
            SM::init(tmp.as_mut_ptr().add(len), C - len);
        }
        Ok(tmp)
    }
}

impl<L, SM, const C: usize> TryFrom<&mut str> for ArrayString<C, L, SM>
where
    L: LengthType,
    SM: SpareMemoryPolicy<u8>,
{
    type Error = InsufficientCapacityError;

    #[inline]
    fn try_from(s: &mut str) -> Result<Self, Self::Error> {
        Self::try_from(s as &str)
    }
}

impl<L, SM, const C: usize> TryFrom<char> for ArrayString<C, L, SM>
where
    L: LengthType,
    SM: SpareMemoryPolicy<u8>,
{
    type Error = InsufficientCapacityError;

    #[inline]
    fn try_from(ch: char) -> Result<Self, Self::Error> {
        let ch_len = ch.len_utf8();
        if ch_len > Self::CAPACITY {
            return Err(InsufficientCapacityError {});
        }
        let mut s = Self::new_raw(ch_len);
        unsafe {
            ch.encode_utf8(slice::from_raw_parts_mut(s.as_mut_ptr(), ch_len));
            SM::init(s.as_mut_ptr().add(ch_len), C - ch_len);
        }
        Ok(s)
    }
}

#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<L, SM, const C: usize> TryFrom<&alloc::string::String> for ArrayString<C, L, SM>
where
    L: LengthType,
    SM: SpareMemoryPolicy<u8>,
{
    type Error = InsufficientCapacityError;

    #[inline]
    fn try_from(string: &alloc::string::String) -> Result<Self, Self::Error> {
        Self::try_from(string.as_str())
    }
}

#[cfg(test)]
mod testing {
    use crate as cds;
    use cds::{
        array_str,
        arraystring::{
            errors::InsufficientCapacityError, test_arraystring::check_spare_memory, ArrayString,
        },
        len::U8,
        mem::Pattern,
    };

    const PATTERN: u8 = 0xAB;

    #[test]
    fn test_try_from_str() {
        type S = ArrayString<255, U8, Pattern<PATTERN>>;
        let s = S::try_from("cds").unwrap();
        assert_eq!(s, "cds");
        check_spare_memory(&s, PATTERN);
    }

    #[test]
    fn test_try_from_mut_str() {
        type S = ArrayString<255, U8, Pattern<PATTERN>>;
        let mut src = array_str![8; "one"];
        let s = S::try_from(src.as_mut_str()).unwrap();
        assert_eq!(s, "one");
        check_spare_memory(&s, PATTERN);
    }

    #[test]
    fn test_try_from_str_err() {
        type S = ArrayString<2, U8, Pattern<PATTERN>>;
        assert!(matches!(S::try_from("cds"), Err(e) if e == InsufficientCapacityError));
    }

    #[test]
    fn test_try_from_mut_str_err() {
        type S = ArrayString<2, U8, Pattern<PATTERN>>;
        let mut src = array_str![8; "one"];
        assert!(matches!(S::try_from(src.as_mut_str()), Err(e) if e == InsufficientCapacityError));
    }

    #[test]
    fn test_try_from_char() {
        type S = ArrayString<16, U8, Pattern<PATTERN>>;
        let s = S::try_from('a').unwrap();
        assert_eq!(s, "a");
        check_spare_memory(&s, PATTERN);
    }

    #[test]
    fn test_try_from_char_fails() {
        type S = ArrayString<2, U8, Pattern<PATTERN>>;
        assert!(matches!(S::try_from(''), Err(e) if e == InsufficientCapacityError));
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn test_try_from_string() {
        let string = alloc::string::String::from("cds");
        type S = ArrayString<16, U8, Pattern<PATTERN>>;
        let s = S::try_from(&string).unwrap();
        assert_eq!(s, "cds");
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn test_try_from_string_fails() {
        let string = alloc::string::String::from("cds");
        type S = ArrayString<2, U8, Pattern<PATTERN>>;
        assert!(matches!(S::try_from(&string), Err(e) if e == InsufficientCapacityError));
    }
}