use typenum::U1;

use crate::*;

impl ToOutput for u8 {
    fn to_output(&self, output: &mut impl Output) {
        if output.is_real() {
            output.write(&[*self]);
        }
    }
}

impl InlineOutput for u8 {
    fn slice_to_output(slice: &[Self], output: &mut impl Output)
    where
        Self: Sized,
    {
        if output.is_real() {
            output.write(slice);
        }
    }
}

impl<I: ParseInput> Parse<I> for u8 {
    fn parse(input: I) -> crate::Result<Self> {
        ParseInline::parse_as_inline(input)
    }
}

impl<I: ParseInput> ParseInline<I> for u8 {
    fn parse_inline(input: &mut I) -> crate::Result<Self> {
        Ok(Self::from_le_bytes(*input.parse_chunk::<1>()?))
    }

    fn parse_vec(input: I) -> crate::Result<Vec<Self>> {
        Ok(input.parse_all()?.into())
    }

    fn parse_array<const N: usize>(input: &mut I) -> crate::Result<[Self; N]> {
        input.parse_chunk().copied()
    }
}

impl Size for u8 {
    type Size = U1;
    const SIZE: usize = 1;
}

impl FromSized for u8 {
    fn from_sized(data: &GenericArray<u8, Self::Size>) -> Self {
        let [byte] = From::from(Clone::clone(data));
        byte
    }
}
