1#![doc = include_str!("../README.md")]
2#![deny(clippy::alloc_instead_of_core)]
3#![deny(clippy::std_instead_of_core)]
4mod cmp;
8mod fmt;
9mod macros;
10mod methods;
11mod new;
12mod refs;
13mod traits;
14
15#[diagnostic::on_unimplemented(
17 message = "`VarStringlet<{SIZE}>` or `SlimStringlet<{SIZE}>` has excessive SIZE",
18 label = "SIZE must be `0..=255` or `0..=64`",
19 note = "`VarStringlet` cannot be longer than 255 bytes. Consider using `String`!",
20 note = "`SlimStringlet` cannot be longer than 64 bytes. Consider using `VarStringlet`!"
21)]
22#[doc(hidden)]
23pub trait Config<Kind, const SIZE: usize, const LEN: usize = 0, const ALIGN: u8 = 1> {
24 type Aligned: Copy + Eq + Ord;
25 const ABBR: u8;
26}
27
28#[derive(Copy, Clone)]
30pub struct Fixed;
31#[derive(Copy, Clone)]
32pub struct Trim;
33#[derive(Copy, Clone)]
34pub struct Var;
35#[derive(Copy, Clone)]
36pub struct Slim;
37
38macro_rules! config {
39 ($kind:ident $msg:literal: $stringlet:ident, $aligned:ident, $len:literal, 1) => {
40 #[doc = concat!($msg, " length Stringlet")]
41 pub type $stringlet<const SIZE: usize = 16> =
42 StringletBase<$kind, SIZE, $len, 1>;
43 };
44 ($kind:ident $msg:literal: $stringlet:ident, $aligned:ident, $len:literal, $align:literal) => {
45 #[doc = concat!($msg, " length Stringlet, aligned to ", $align, " bytes")]
46 pub type $stringlet<const SIZE: usize = 16> =
47 StringletBase<$kind, SIZE, $len, $align>;
48 };
49 ($($stringlet:ident, $trim_stringlet:ident, $var_stringlet:ident, $slim_stringlet:ident: $aligned:ident @ $align:literal;)+) => {
50 $(
51 #[doc(hidden)]
52 #[repr(align($align))]
53 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
54 pub struct $aligned;
55 )+
56 $(
57 config!(Fixed "Fixed": $stringlet, $aligned, 0, $align);
58 config!(Trim "Trimmed": $trim_stringlet, $aligned, 0, $align);
59 config!(Var "Variable": $var_stringlet, $aligned, 1, $align);
60 config!(Slim "Slim variable": $slim_stringlet, $aligned, 0, $align);
61
62 config![ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
65 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
66 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64: $aligned @ $align
67 ];
68 config![ + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
70 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
71 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
72 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
73 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
74 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
75 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
76 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
77 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
78 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255: Var $aligned @ 1, $align
79 ];
80 )+
81 };
82 ($($size:tt),+: $aligned:ident @ $align:literal) => {
83 config![+ SIZE: Fixed $aligned @ $align];
88 config![+ SIZE: Trim $aligned @ $align];
89 config![+ $($size),+: Var $aligned @ 1, $align];
90 config![+ $($size),+: Slim $aligned @ 0, $align];
91 };
92 (+ SIZE: $kind:ident $aligned:ident @ $align:literal) => {
93 impl<const SIZE: usize> Config<$kind, SIZE, 0, $align>
94 for StringletBase<$kind, SIZE, 0, $align>
95 {
96 type Aligned = $aligned;
97 const ABBR: u8 = stringify!($kind).as_bytes()[0];
98 }
99 };
100 (+ $($size:tt),+: $kind:ident $aligned:ident @ $len:literal, $align:literal) => {
101 $(
102 impl Config<$kind, $size, $len, $align>
103 for StringletBase<$kind, $size, $len, $align>
104 {
105 type Aligned = $aligned;
106 const ABBR: u8 = stringify!($kind).as_bytes()[0];
107 }
108 )+
109 };
110}
111
112config! {
113 Stringlet, TrimStringlet, VarStringlet, SlimStringlet: Align1 @ 1;
114 Stringlet2, TrimStringlet2, VarStringlet2, SlimStringlet2: Align2 @ 2;
115 Stringlet4, TrimStringlet4, VarStringlet4, SlimStringlet4: Align4 @ 4;
116 Stringlet8, TrimStringlet8, VarStringlet8, SlimStringlet8: Align8 @ 8;
117 Stringlet16, TrimStringlet16, VarStringlet16, SlimStringlet16: Align16 @ 16;
118 Stringlet32, TrimStringlet32, VarStringlet32, SlimStringlet32: Align32 @ 32;
119 Stringlet64, TrimStringlet64, VarStringlet64, SlimStringlet64: Align64 @ 64;
120}
121
122#[derive(Copy, Clone)]
124pub struct StringletBase<
125 Kind,
126 const SIZE: usize,
127 const LEN: usize = 0,
130 const ALIGN: u8 = 1,
131> where
132 Self: Config<Kind, SIZE, LEN, ALIGN>,
133{
134 pub(crate) _align: [<Self as Config<Kind, SIZE, LEN, ALIGN>>::Aligned; 0],
136 pub(crate) str: [u8; SIZE],
138 pub(crate) len: [u8; LEN],
141}
142
143macro_rules! self2 {
145 () => {
146 StringletBase<Kind2, SIZE2, LEN2, ALIGN2>
147 };
148}
149
150macro_rules! impl_for {
159 (<$($lt:lifetime)? $(,)? $(2 $($two:literal)?)?> $trait:ty $(: $($rest:tt)+)?) => {
162 impl_for!(@ $(2 $($two)?)? $($lt)?; $trait: $($($rest)+)?);
163 };
164 ($trait:ty $(: $($rest:tt)+)?) => {
165 impl_for!(@ ; $trait: $($($rest)+)?);
166 };
167
168 (@ $(2 $($two:literal)?)? $($lt:lifetime)?; $trait:ty: $($rest:tt)*) => {
169 impl_for!(@@
170 $(2 $($two)?)?
171 $($lt)?
172 [Kind, const SIZE: usize, const LEN: usize, const ALIGN: u8,]
173 [StringletBase<Kind, SIZE, LEN, ALIGN>: Config<Kind, SIZE, LEN, ALIGN>,]
174 $trait:
175 $($rest)*
176 );
177 };
178 (@@ 2 $($lt:lifetime)? [$($gen:tt)+] [$($where:tt)+] $trait:ty: $($rest:tt)*) => {
179 impl_for!(@@
180 $($lt)?
181 [$($gen)+ Kind2, const SIZE2: usize, const LEN2: usize, const ALIGN2: u8]
182 [$($where)+ self2!(): Config<Kind2, SIZE2, LEN2, ALIGN2>,]
183 $trait:
184 $($rest)*
185 );
186 };
187 (@@ $($lt:lifetime)? [$($gen:tt)+] [$($where:tt)+] $trait:ty: $($rest:tt)*) => {
188 impl<$($lt,)? $($gen)+> $trait
189 for StringletBase<Kind, SIZE, LEN, ALIGN>
190 where $($where)+
191 {
192 $($rest)*
193 }
194 };
195}
196
197pub(crate) use impl_for;
198pub(crate) use self2;