use tinyvec::ArrayVec;
mod array_string;
mod data_vec;
mod grid16p;
#[cfg(feature = "serde")]
use crate::{Deserialize, Serialize, Visitor};
#[allow(unused)]
pub use array_string::ArrayString;
use core::{fmt::Write, slice::Iter};
pub use data_vec::DataVec;
pub use grid16p::Grid16P;
#[derive(Clone, PartialEq)]
pub struct Df88591String<const N: usize>(ArrayVec<[u8; N]>);
impl<const N: usize> Df88591String<N> {
    pub fn new() -> Self {
        Df88591String(ArrayVec::new())
    }
    pub fn chars(&self) -> Df88591StringChars<'_> {
        Df88591StringChars {
            iter: self.0.iter(),
        }
    }
    pub fn iter(&self) -> Iter<'_, u8> {
        self.0.iter()
    }
    pub fn len(&self) -> usize {
        self.0.len()
    }
    pub fn push(&mut self, val: u8) {
        self.0.push(if val == 0 { 0xa4 } else { val });
    }
    pub fn push_char(&mut self, ch: char) {
        self.0.push(Df88591StringChars::<'_>::from_char(ch));
    }
    #[inline]
    pub fn try_push(&mut self, ch: char) -> Result<(), ()> {
        if self.0.len() + 1 > self.0.capacity() {
            return Err(());
        }
        self.0.push(Df88591StringChars::<'_>::from_char(ch));
        Ok(())
    }
}
impl<const N: usize> From<&str> for Df88591String<N> {
    fn from(value: &str) -> Self {
        value.chars().collect()
    }
}
impl<const N: usize> FromIterator<char> for Df88591String<N> {
    fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Df88591String<N> {
        let mut buf = Df88591String::new();
        for c in iter.into_iter() {
            if buf.try_push(c).is_err() {
                break;
            }
        }
        buf
    }
}
impl<const N: usize> Default for Df88591String<N> {
    fn default() -> Self {
        Df88591String::new()
    }
}
impl<const N: usize> core::fmt::Display for Df88591String<N> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "Df88591String<{}>(\"", N)?;
        for c in self.chars() {
            f.write_char(c)?;
        }
        f.write_str("\")")
    }
}
impl<const N: usize> core::fmt::Debug for Df88591String<N> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let val: ArrayVec<[char; N]> = self
            .0
            .iter()
            .map(|v| Df88591StringChars::to_char(*v))
            .collect();
        f.debug_tuple("Df88591String").field(&val).finish()
    }
}
pub struct Df88591StringChars<'a> {
    iter: core::slice::Iter<'a, u8>,
}
impl Df88591StringChars<'_> {
    fn to_char(code: u8) -> char {
        if code == 0 {
            char::from_u32(0xa4).unwrap()
        } else {
            char::from_u32(code as u32).unwrap()
        }
    }
    fn from_char(ch: char) -> u8 {
        let code = ch as u32;
        if code > 0 && code < 256 {
            code as u8
        } else {
            0xa4
        }
    }
}
impl<'a> Iterator for Df88591StringChars<'a> {
    type Item = char;
    #[inline]
    fn next(&mut self) -> Option<char> {
        Some(Df88591StringChars::to_char(*self.iter.next()?))
    }
    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.iter.len();
        (len, Some(len))
    }
}
#[cfg(feature = "serde")]
impl<const N: usize> Serialize for Df88591String<N> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: sd::Serializer,
    {
        let value: ArrayString<N> = self.chars().collect();
        serializer.serialize_str(&value)
    }
}
#[cfg(feature = "serde")]
impl<'de, const N: usize> Deserialize<'de> for Df88591String<N> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: sd::Deserializer<'de>,
    {
        struct Str88591Visitor<const N: usize>;
        impl<'de, const N: usize> Visitor<'de> for Str88591Visitor<N> {
            type Value = Df88591String<N>;
            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
                formatter.write_str("an ISO 8859-1 encoded string")
            }
            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
                let mut value = Df88591String::<N>::new();
                for ch in v.chars().take(N) {
                    value.push_char(ch);
                }
                Ok(value)
            }
        }
        deserializer.deserialize_str(Str88591Visitor::<N>)
    }
}
#[cfg(feature = "test_gen")]
use crate::source_repr::SourceRepr;
#[cfg(feature = "test_gen")]
impl<const N: usize> SourceRepr for Df88591String<N> {
    fn to_source(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let s = self.chars().collect::<ArrayString<N>>();
        write!(f, "Df88591String::<{}>::from(\"{}\")", N, s.as_ref())
    }
}