1#![allow(non_camel_case_types)]
2
3use crate::fmt::{Error, StrWriter};
4
5use core::marker::PhantomData;
6
7macro_rules! type_level_error {
8 (
9 arguments($($args:tt)*)
10
11 $($error:ident => $error_ty:ident<$($error_param:ident),*> ,)*
12 ) => {
13 type_level_error!{
14 @inner
15 arguments($($args)*)
16
17 Result::Ok(()), Ok => Ok<>,
18 $(
19 Result::Err(Error::$error), $error => $error_ty<$($error_param),*>,
20 )*
21 }
22 };
23 (@inner
24 arguments($cap:ident)
25
26 $($matched:pat , $error:ident => $error_ty:ident<$($error_param:ident),*> ,)*
27 ) => {
28
29 enum ErrorKind {
30 $($error,)*
31 }
32
33 impl ErrorTuple {
34 pub const EMPTY: ErrorTuple = ErrorTuple{
35 error_variant: ErrorKind::Ok as usize,
36 capacity: 0,
37 };
38
39 pub const fn new(opt: Result<(), Error>, writer: &StrWriter) -> Self{
40 let variant = match opt {
41 $($matched => ErrorKind::$error as usize,)*
42 };
43
44 Self{
45 error_variant: variant,
46 capacity: writer.capacity(),
47 }
48 }
49
50 }
51
52
53 $(
54 pub struct $error_ty<$($error_param,)*>(PhantomData<($($error_param,)*)>);
55
56 impl<$($error_param,)*> $error_ty<$($error_param,)*> {
57 pub const NEW: Self = Self(PhantomData);
58 }
59
60 impl<$cap> ErrorAsType for ErrorPicker<[(); ErrorKind::$error as usize], $cap> {
61 type Type = $error_ty<$($error_param,)*>;
62 }
63 )*
64 }
65}
66
67pub struct ErrorTupleAndStrWriter<A> {
68 pub error: ErrorTuple,
69 pub writer: StrWriter<A>,
70}
71
72pub struct ErrorPicker<E, Cap>(PhantomData<fn() -> (E, Cap)>);
73
74pub struct ErrorTuple {
75 pub error_variant: usize,
76 pub capacity: usize,
77}
78
79pub trait ErrorAsType {
80 type Type;
81}
82
83type_level_error! {
84 arguments(cap)
85
86 NotEnoughSpace => not_enough_space_to_write_text_in_StrWriter_with_this_capacity<cap>,
87
88 NotAscii => input_text_was_not_ascii<>,
89
90 NotOnCharBoundary => NotOnCharBoundary<>,
91}