1use crate::{
2 fmt::{FmtArg, PackedFmtArg, PanicFmt},
3 panic_val::{PanicVal, PanicVariant},
4 utils::Packed,
5 StdWrapper,
6};
7
8macro_rules! impl_panicfmt_array {
9 ($(($variant:ident, $panicval_ctor:ident, $ty:ty)),* $(,)*) => {
10
11 #[derive(Copy, Clone)]
12 #[repr(packed)]
13 pub(crate) struct Slice<'s> {
14 pub(crate) fmtarg: PackedFmtArg,
15 pub(crate) vari: SliceV<'s>,
16 }
17
18 #[repr(u8)]
19 #[derive(Copy, Clone)]
20 pub(crate) enum SliceV<'s> {
21 $(
22 $variant(Packed<&'s [$ty]>),
23 )*
24 }
25
26
27 impl<'s> Slice<'s> {
28 pub(crate) const fn arr_len(self) -> usize {
30 match self.vari {
31 $(
32 SliceV::$variant(Packed(arr)) => arr.len(),
33 )*
34 }
35 }
36 }
37
38 impl<'s> SliceV<'s> {
39 const fn get(self, index: usize, fmtarg: FmtArg) -> PanicVal<'s> {
40 match self {
41 $(
42 SliceV::$variant(Packed(arr)) => {
43 let elem: &'s <$ty as PanicFmt>::This = &arr[index];
44 StdWrapper(elem).to_panicval(fmtarg)
45 },
46 )*
47 }
48 }
49 }
50
51 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "non_basic")))]
52 impl<'s> PanicVal<'s> {
53 $(
54 pub const fn $panicval_ctor(this: &'s [$ty], mut fmtarg: FmtArg) -> PanicVal<'s> {
56 fmtarg = fmtarg.indent();
57 if this.is_empty() {
58 fmtarg = fmtarg.set_alternate(false);
59 }
60 PanicVal::__new(
61 PanicVariant::Slice(Slice{
62 fmtarg: fmtarg.pack(),
63 vari: SliceV::$variant(Packed(this)),
64 })
65 )
66 }
67 )*
68 }
69
70 $(
71 impl<'s> PanicFmt for [$ty] {
72 type This = Self;
73 type Kind = crate::fmt::IsStdType;
74 const PV_COUNT: usize = 1;
75 }
76 impl<'s, const LEN: usize> PanicFmt for [$ty; LEN] {
77 type This = Self;
78 type Kind = crate::fmt::IsStdType;
79 const PV_COUNT: usize = 1;
80 }
81
82 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "non_basic")))]
83 impl<'s> StdWrapper<&'s [$ty]> {
84 pub const fn to_panicvals(self: Self, f:FmtArg) -> [PanicVal<'s>;1] {
86 [PanicVal::$panicval_ctor(self.0, f)]
87 }
88 pub const fn to_panicval(self: Self, f:FmtArg) -> PanicVal<'s> {
90 PanicVal::$panicval_ctor(self.0, f)
91 }
92 }
93
94 #[cfg_attr(feature = "docsrs", doc(cfg(feature = "non_basic")))]
95 impl<'s, const LEN: usize> StdWrapper<&'s [$ty; LEN]> {
96 pub const fn to_panicvals(self: Self, f:FmtArg) -> [PanicVal<'s>;1] {
98 [PanicVal::$panicval_ctor(self.0, f)]
99 }
100 pub const fn to_panicval(self: Self, f:FmtArg) -> PanicVal<'s> {
102 PanicVal::$panicval_ctor(self.0, f)
103 }
104 }
105 )*
106
107 };
108}
109
110impl_panicfmt_array! {
111 (U8, from_slice_u8, u8),
112 (U16, from_slice_u16, u16),
113 (U32, from_slice_u32, u32),
114 (U64, from_slice_u64, u64),
115 (U128, from_slice_u128, u128),
116 (Usize, from_slice_usize, usize),
117 (I8, from_slice_i8, i8),
118 (I16, from_slice_i16, i16),
119 (I32, from_slice_i32, i32),
120 (I64, from_slice_i64, i64),
121 (I128, from_slice_i128, i128),
122 (Isize, from_slice_isize, isize),
123 (Bool, from_slice_bool, bool),
124 (Char, from_slice_char, char),
125 (Str, from_slice_str, &'s str),
126}
127
128#[derive(Copy, Clone)]
129pub(crate) struct SliceIter<'s> {
130 slice: SliceV<'s>,
131 fmtarg: FmtArg,
132 state: IterState,
133 arr_len: u32,
134}
135
136#[derive(Copy, Clone, PartialEq, Eq)]
137struct IterState(u32);
138
139#[allow(non_upper_case_globals)]
140impl IterState {
141 const Start: Self = Self(u32::MAX - 1);
142 const End: Self = Self(u32::MAX);
143}
144
145impl<'s> Slice<'s> {
146 pub(crate) const fn iter<'b>(&'b self) -> SliceIter<'s> {
147 SliceIter {
148 slice: self.vari,
149 fmtarg: self.fmtarg.unpack(),
150 state: IterState::Start,
151 arr_len: self.arr_len() as u32,
152 }
153 }
154}
155
156impl<'s> SliceIter<'s> {
157 pub(crate) const fn next(mut self) -> ([PanicVal<'s>; 2], Option<Self>) {
158 let fmtarg = self.fmtarg;
159
160 let ret = match self.state {
161 IterState::Start => {
162 self.state = if self.arr_len == 0 {
163 IterState::End
164 } else {
165 IterState(0)
166 };
167
168 [crate::fmt::OpenBracket.to_panicval(fmtarg), PanicVal::EMPTY]
169 }
170 IterState::End => {
171 let close_brace = crate::fmt::CloseBracket.to_panicval(fmtarg.unindent());
172 return ([close_brace, PanicVal::EMPTY], None);
173 }
174 IterState(x) => {
175 let comma = if x + 1 == self.arr_len {
176 self.state = IterState::End;
177 crate::fmt::COMMA_TERM
178 } else {
179 self.state = IterState(x + 1);
180 crate::fmt::COMMA_SEP
181 }
182 .to_panicval(fmtarg);
183
184 [self.slice.get(x as usize, fmtarg), comma]
185 }
186 };
187
188 (ret, Some(self))
189 }
190}