1use std::marker::PhantomData;
2
3use derive_ex::derive_ex;
4
5use crate::{CellsFormatter, RawCell};
6
7pub use text_grid_macros::Cells;
13
14pub trait Cells {
20 fn fmt(f: &mut CellsFormatter<Self>);
22}
23impl Cells for () {
24 fn fmt(_: &mut CellsFormatter<Self>) {}
25}
26impl<T: ?Sized + Cells> Cells for &T {
27 fn fmt(f: &mut CellsFormatter<Self>) {
28 T::fmt(&mut f.unref());
29 }
30}
31impl<T: ?Sized + Cells> Cells for &mut T {
32 fn fmt(f: &mut CellsFormatter<Self>) {
33 T::fmt(&mut f.unref());
34 }
35}
36impl<T: Cells, const N: usize> Cells for [T; N] {
37 fn fmt(f: &mut CellsFormatter<Self>) {
38 for i in 0..N {
39 f.column(i, |x| &x[i]);
40 }
41 }
42}
43impl<T: Cells> Cells for Option<T> {
44 fn fmt(f: &mut CellsFormatter<Self>) {
45 f.filter_map(|x| x.as_ref()).content(|x| x)
46 }
47}
48impl<T: Cells, E: RawCell> Cells for std::result::Result<T, E> {
49 fn fmt(f: &mut CellsFormatter<Self>) {
50 f.try_map_with(|x| x.as_ref(), |f| T::fmt(&mut f.unref()));
51 }
52}
53
54pub trait CellsSchema {
92 type Source: ?Sized;
93
94 fn fmt(&self, f: &mut CellsFormatter<Self::Source>);
96}
97
98pub trait CellsSchemaExt: CellsSchema {
100 fn as_ref(&self) -> impl CellsSchema<Source = &Self::Source> {
101 self.map_ref()
102 }
103 fn map_ref<'a>(self) -> impl CellsSchema<Source = &'a Self::Source>
104 where
105 Self::Source: 'a;
106}
107impl<T> CellsSchemaExt for T
108where
109 T: CellsSchema,
110{
111 fn map_ref<'a>(self) -> impl CellsSchema<Source = &'a Self::Source>
112 where
113 Self::Source: 'a,
114 {
115 cells_schema(move |f| self.fmt(&mut f.map(|x| *x)))
116 }
117}
118
119impl<T: CellsSchema> CellsSchema for Vec<T> {
120 type Source = T::Source;
121 fn fmt(&self, f: &mut CellsFormatter<Self::Source>) {
122 for s in self {
123 s.fmt(f);
124 }
125 }
126}
127impl<T: CellsSchema> CellsSchema for [T] {
128 type Source = T::Source;
129 fn fmt(&self, f: &mut CellsFormatter<Self::Source>) {
130 for s in self {
131 s.fmt(f);
132 }
133 }
134}
135impl<T: ?Sized + CellsSchema> CellsSchema for &T {
136 type Source = T::Source;
137 fn fmt(&self, f: &mut CellsFormatter<Self::Source>) {
138 T::fmt(self, f)
139 }
140}
141
142#[derive(Clone, Copy, Debug)]
144#[derive_ex(Default(bound()))]
145pub struct DefaultCellsSchema<T: ?Sized>(PhantomData<T>);
146
147impl<T: Cells + ?Sized> CellsSchema for DefaultCellsSchema<T> {
148 type Source = T;
149 fn fmt(&self, f: &mut CellsFormatter<Self::Source>) {
150 T::fmt(f);
151 }
152}
153
154pub fn cells_schema<T: ?Sized>(
182 fmt: impl Fn(&mut CellsFormatter<T>),
183) -> impl CellsSchema<Source = T> {
184 struct FnCellsSchema<T: ?Sized, F> {
185 fmt: F,
186 _phantom: PhantomData<fn(&mut CellsFormatter<T>)>,
187 }
188
189 impl<T: ?Sized, F: Fn(&mut CellsFormatter<T>)> CellsSchema for FnCellsSchema<T, F> {
190 type Source = T;
191 fn fmt(&self, f: &mut CellsFormatter<T>) {
192 (self.fmt)(f)
193 }
194 }
195 FnCellsSchema {
196 fmt,
197 _phantom: PhantomData,
198 }
199}
200
201macro_rules! impl_for_tuple {
202 ($($idx:tt : $ty:ident,)*) => {
203 impl<$($ty),*> Cells for ($($ty,)*) where $($ty: Cells),* {
204 fn fmt(f: &mut CellsFormatter<Self>) {
205 $(
206 f.map_with(|x| &x.$idx, Cells::fmt);
207 )*
208 }
209 }
210
211 impl<$($ty),*> CellsSchema for ($($ty,)*)
212 where
213 $($ty: CellsSchema, $ty::Source: Sized,)*
214 {
215 type Source = ($($ty::Source,)*);
216 fn fmt(&self, f: &mut CellsFormatter<Self::Source>) {
217 $(self.$idx.fmt(&mut f.map(|x| &x.$idx));)*
218 }
219 }
220 };
221}
222
223impl_for_tuple!(0: T0,);
224impl_for_tuple!(0: T0, 1: T1,);
225impl_for_tuple!(0: T0, 1: T1, 2: T2,);
226impl_for_tuple!(0: T0, 1: T1, 2: T2, 3: T3,);
227impl_for_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4,);
228impl_for_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5,);
229impl_for_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6,);
230impl_for_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7,);
231impl_for_tuple!(
232 0: T0,
233 1: T1,
234 2: T2,
235 3: T3,
236 4: T4,
237 5: T5,
238 6: T6,
239 7: T7,
240 8: T8,
241);
242impl_for_tuple!(
243 0: T0,
244 1: T1,
245 2: T2,
246 3: T3,
247 4: T4,
248 5: T5,
249 6: T6,
250 7: T7,
251 8: T8,
252 9: T9,
253);
254impl_for_tuple!(
255 0: T0,
256 1: T1,
257 2: T2,
258 3: T3,
259 4: T4,
260 5: T5,
261 6: T6,
262 7: T7,
263 8: T8,
264 9: T9,
265 10: T10,
266);
267impl_for_tuple!(
268 0: T0,
269 1: T1,
270 2: T2,
271 3: T3,
272 4: T4,
273 5: T5,
274 6: T6,
275 7: T7,
276 8: T8,
277 9: T9,
278 10: T10,
279 11: T11,
280);
281impl_for_tuple!(
282 0: T0,
283 1: T1,
284 2: T2,
285 3: T3,
286 4: T4,
287 5: T5,
288 6: T6,
289 7: T7,
290 8: T8,
291 9: T9,
292 10: T10,
293 11: T11,
294 12: T12,
295);
296impl_for_tuple!(
297 0: T0,
298 1: T1,
299 2: T2,
300 3: T3,
301 4: T4,
302 5: T5,
303 6: T6,
304 7: T7,
305 8: T8,
306 9: T9,
307 10: T10,
308 11: T11,
309 12: T12,
310 13: T13,
311);
312impl_for_tuple!(
313 0: T0,
314 1: T1,
315 2: T2,
316 3: T3,
317 4: T4,
318 5: T5,
319 6: T6,
320 7: T7,
321 8: T8,
322 9: T9,
323 10: T10,
324 11: T11,
325 12: T12,
326 13: T13,
327 14: T14,
328);
329impl_for_tuple!(
330 0: T0,
331 1: T1,
332 2: T2,
333 3: T3,
334 4: T4,
335 5: T5,
336 6: T6,
337 7: T7,
338 8: T8,
339 9: T9,
340 10: T10,
341 11: T11,
342 12: T12,
343 13: T13,
344 14: T14,
345 15: T15,
346);