#![feature(prelude_import)]
#![doc(html_root_url = "https://docs.rs/fixed_len_str_example/0.1.3/")]
#![no_std]
//! This crate contains an example of the struct generated by the procedural macro contained in [fixed_len_str],use that
//! macro instead.
#[prelude_import]
use core::prelude::v1::*;
#[macro_use]
extern crate core;
#[macro_use]
extern crate compiler_builtins;
use fixed_len_str::fixed_len_str;
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
use core::ops::{Deref, DerefMut};
use core::convert::{AsRef, AsMut};
use core::hash::{Hasher, Hash};
use core::cmp::Ordering;
/// A fixed length string with a length of 12.
#[repr(transparent)]
pub struct FixedStr12 {
    pub array: [u8; 12],
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for FixedStr12 {
    #[inline]
    fn clone(&self) -> FixedStr12 {
        match *self {
            FixedStr12 {
                array: ref __self_0_0,
            } => FixedStr12 {
                array: ::core::clone::Clone::clone(&(*__self_0_0)),
            },
        }
    }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for FixedStr12 {
    #[inline]
    fn default() -> FixedStr12 {
        FixedStr12 {
            array: ::core::default::Default::default(),
        }
    }
}
impl FixedStr12 {
    /// Creates an FixedStr12 from an array,in the future this will be unsafe because it does not checks if the bytes are
    /// valid utf8.
    #[inline]
    pub const fn new(array: [u8; 12]) -> Self {
        Self { array }
    }
    /// Borrow the internal array as an slice.
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        &self.array[..]
    }
    /// Borrow the internal array as a mutable slice.
    ///
    /// # Safety
    ///
    /// This is unsafe due to allow modifications that can produce invalid utf8.
    #[inline]
    pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
        &mut self.array[..]
    }
    /// Fill the last spaces in zero of the buffer with a determinated character.Useful when constructing the array with all bytes in
    /// zero and then filling them in an incremental way.
    ///
    /// # Panics
    ///
    /// This will panic on debug if the zero spaces are not sufficient for the non-zero spaces of the character interpreted as
    /// `\[u8; 4\]`.
    #[inline]
    pub fn fill_zeroes_char(&mut self, character: char) {
        let position = self.array.iter().position(|e| *e == 0u8).unwrap_or(12);
        let character = unsafe { core::mem::transmute::<char, [u8; 4]>(character) };
        if true {
            if !((&self.array[position..]).len()
                >= character.iter().position(|e| *e == 0u8).unwrap_or(4))
            {
                :: core :: panicking :: panic ( "assertion failed: (&self.array[position..]).len() >=\n    character.iter().position(|e| *e == 0u8).unwrap_or(4)" )
            };
        };
        for (e, c) in self.array[position..].iter_mut().zip(character.iter()) {
            *e = *c;
        }
    }
    /// Fill the last spaces in zero of the buffer with a determinated string.Useful when constructing the array with all bytes in
    /// zero and then filling them in an incremental way.
    ///
    /// # Panics
    ///
    /// This will panic on debug if the zero spaces are not sufficient for the non-zero spaces of the string interpreted as
    /// `&\[u8\]`.
    #[inline]
    pub fn fill_zeroes_str(&mut self, s: &str) {
        let position = self.array.iter().position(|e| *e == 0u8).unwrap_or(12);
        if true {
            if !((&self.array[position..]).len()
                >= s.as_bytes()
                    .iter()
                    .position(|e| *e == 0u8)
                    .unwrap_or(s.len()))
            {
                :: core :: panicking :: panic ( "assertion failed: (&self.array[position..]).len() >=\n    s.as_bytes().iter().position(|e| *e == 0u8).unwrap_or(s.len())" )
            };
        };
        for (e, c) in self.array[position..].iter_mut().zip(s.as_bytes().iter()) {
            *e = *c;
        }
    }
    /// Convert the FixedStr12 into a vector of bytes.
    #[inline]
    pub fn into_vec(self) -> Vec<u8> {
        let arr = core::mem::ManuallyDrop::new(self.array);
        let mut buf = Vec::with_capacity(12);
        unsafe {
            arr.as_ptr().copy_to(buf.as_mut_ptr(), 12);
            buf.set_len(12)
        }
        buf
    }
    /// Turn the FixedStr12 into a string,moving the bytes.
    #[inline]
    pub fn into_string(self) -> String {
        let mut vec = core::mem::ManuallyDrop::new(self.into_vec());
        unsafe { String::from_raw_parts(vec.as_mut_ptr(), vec.len(), vec.capacity()) }
    }
    /// Construct a FixedStr12 from a vector of bytes,truncating or pushing zeroes to adjust the size to 12.
    ///
    /// Using this function with multi-byte characters can easely produce an unexpected value.
    #[inline]
    pub fn from_vec(mut vec: Vec<u8>) -> FixedStr12 {
        use core::mem::{transmute, MaybeUninit};
        if vec.len() > 12 {
            vec.truncate(12);
        } else if vec.len() < 12 {
            vec.reserve(12 - vec.len());
            while vec.len() < vec.capacity() {
                vec.push(0);
            }
        }
        let mut array = [MaybeUninit::uninit(); 12];
        let vec = unsafe { transmute::<Vec<u8>, Vec<MaybeUninit<u8>>>(vec) };
        unsafe { vec.as_ptr().copy_to(array.as_mut_ptr(), 12) };
        core::mem::forget(vec);
        Self {
            array: unsafe { transmute(array) },
        }
    }
    /// Construct a FixedStr12 from a String,truncating or pushing zeroes to adjust the size to 12.
    ///
    /// Using this function with multi-byte characters can easely produce an unexpected value.
    #[inline]
    pub fn from_string(string: String) -> FixedStr12 {
        Self::from_vec(string.into_boxed_str().into_boxed_bytes().into_vec())
    }
}
impl Display for FixedStr12 {
    fn fmt(&self, f: &'_ mut Formatter) -> FmtResult {
        f.write_fmt(::core::fmt::Arguments::new_v1(
            &[""],
            &match (&self.as_ref(),) {
                (arg0,) => [::core::fmt::ArgumentV1::new(
                    arg0,
                    ::core::fmt::Display::fmt,
                )],
            },
        ))
    }
}
impl Debug for FixedStr12 {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.write_fmt(::core::fmt::Arguments::new_v1(
            &[""],
            &match (&self,) {
                (arg0,) => [::core::fmt::ArgumentV1::new(
                    arg0,
                    ::core::fmt::Display::fmt,
                )],
            },
        ))
    }
}
impl Deref for FixedStr12 {
    type Target = str;
    #[inline]
    fn deref(&self) -> &Self::Target {
        let mut index = 0;
        for (i, e) in self.as_bytes().iter().rev().enumerate() {
            if *e != 0 {
                index = 12 - i;
                break;
            }
        }
        unsafe { core::str::from_utf8_unchecked(&self.array[..index]) }
    }
}
impl DerefMut for FixedStr12 {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        let mut index = 0;
        for (i, e) in self.as_bytes().iter().rev().enumerate() {
            if *e != 0 {
                index = 12 - i;
                break;
            }
        }
        unsafe { core::str::from_utf8_unchecked_mut(&mut self.array[..index]) }
    }
}
impl AsRef<str> for FixedStr12 {
    fn as_ref(&self) -> &str {
        <Self as core::ops::Deref>::deref(self)
    }
}
impl AsMut<str> for FixedStr12 {
    fn as_mut(&mut self) -> &mut str {
        <Self as core::ops::DerefMut>::deref_mut(self)
    }
}
impl From<&str> for FixedStr12 {
    /// Reinterprets the bytes of `s` as `&[u8; 12]` then dereferences and pass that to the constructor of FixedStr12.
    ///
    /// # Panics
    ///
    /// This will panic if the length of `s` is different than 12 on debug.
    fn from(s: &str) -> Self {
        if true {
            {
                match (&s.len(), &12) {
                    (left_val, right_val) => {
                        if !(*left_val == *right_val) {
                            ::core::panicking::panic_fmt(
                                ::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                ::core::panic::Location::caller(),
                            )
                        }
                    }
                }
            };
        };
        FixedStr12::new(*unsafe {
            core::mem::transmute_copy::<&'_ [u8], &'_ [u8; 12]>(&s.as_bytes())
        })
    }
}
impl From<Vec<u8>> for FixedStr12 {
    fn from(v: Vec<u8>) -> Self {
        Self::from_vec(v)
    }
}
impl From<String> for FixedStr12 {
    fn from(s: String) -> Self {
        Self::from_string(s)
    }
}
impl PartialEq<str> for FixedStr12 {
    fn eq(&self, other: &str) -> bool {
        self.as_ref() == other
    }
}
impl PartialEq<&str> for FixedStr12 {
    fn eq(&self, other: &&str) -> bool {
        self.as_ref() == *other
    }
}
impl PartialEq for FixedStr12 {
    fn eq(&self, other: &Self) -> bool {
        self.as_ref() == other.as_ref()
    }
}
impl Eq for FixedStr12 {}
impl Hash for FixedStr12 {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.as_ref().hash(state)
    }
}
impl PartialOrd for FixedStr12 {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.as_ref().partial_cmp(other.as_ref())
    }
}
impl Ord for FixedStr12 {
    fn cmp(&self, other: &Self) -> Ordering {
        self.as_ref().cmp(other.as_ref())
    }
}
use serde::{Serialize, Deserialize, Serializer, Deserializer};
use serde::de;
/// Only expanded in the original crate with the feature "serde_support" enabled.
impl Serialize for FixedStr12 {
    fn serialize<S: Serializer>(&'_ self, serializer: S) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.as_ref())
    }
}
struct FixedStr12Visitor;
impl<'de> de::Visitor<'de> for FixedStr12Visitor {
    type Value = FixedStr12;
    fn expecting<'a>(&'a self, formatter: &'a mut Formatter) -> FmtResult {
        formatter.write_str("a string containing exactly 12 bytes")
    }
    fn visit_str<E: de::Error>(self, s: &'_ str) -> Result<Self::Value, E> {
        if s.len() == 12 {
            Ok({
                if true {
                    {
                        match (&s.len(), &12) {
                            (left_val, right_val) => {
                                if !(*left_val == *right_val) {
                                    ::core::panicking::panic_fmt(
                                        ::core::fmt::Arguments::new_v1(
                                            &[
                                                "assertion failed: `(left == right)`\n  left: `",
                                                "`,\n right: `",
                                                "`",
                                            ],
                                            &match (&&*left_val, &&*right_val) {
                                                (arg0, arg1) => [
                                                    ::core::fmt::ArgumentV1::new(
                                                        arg0,
                                                        ::core::fmt::Debug::fmt,
                                                    ),
                                                    ::core::fmt::ArgumentV1::new(
                                                        arg1,
                                                        ::core::fmt::Debug::fmt,
                                                    ),
                                                ],
                                            },
                                        ),
                                        ::core::panic::Location::caller(),
                                    )
                                }
                            }
                        }
                    };
                };
                FixedStr12::new(*unsafe {
                    core::mem::transmute_copy::<&'_ [u8], &'_ [u8; 12]>(&s.as_bytes())
                })
            })
        } else {
            let sel: &'_ Self = &self;
            Err(de::Error::invalid_value(de::Unexpected::Str(s), sel))
        }
    }
}
/// Only expanded in the original crate with the feature "serde_support" enabled.
impl<'de> Deserialize<'de> for FixedStr12 {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        deserializer.deserialize_str(FixedStr12Visitor)
    }
}
