cgp_field/traits/
static_string.rs1use crate::types::{Chars, Nil, Symbol};
2
3pub trait StaticString {
4 const VALUE: &'static str;
5}
6
7impl<T> StaticString for T
8where
9 T: StaticBytes,
10{
11 const VALUE: &'static str = const {
12 match str::from_utf8(T::BYTES) {
13 Ok(value) => value,
14 Err(_) => panic!("error const decoding &[u8] to &str"),
15 }
16 };
17}
18
19trait StaticBytes {
20 const BYTES: &'static [u8];
21}
22
23trait MaybeChars {
24 const VALUE: Option<char>;
25
26 type Next: MaybeChars;
27}
28
29impl<const LEN: usize, Chars> StaticBytes for Symbol<LEN, Chars>
30where
31 Chars: MaybeChars,
32{
33 const BYTES: &'static [u8] = &static_chars::<LEN, Chars>();
34}
35
36impl StaticBytes for Nil {
37 const BYTES: &'static [u8] = &[];
38}
39
40impl<const CHAR: char, Tail> MaybeChars for Chars<CHAR, Tail>
41where
42 Tail: MaybeChars,
43{
44 const VALUE: Option<char> = Some(CHAR);
45
46 type Next = Tail;
47}
48
49impl MaybeChars for Nil {
50 const VALUE: Option<char> = None;
51
52 type Next = Nil;
53}
54
55const fn static_chars<const LEN: usize, S: MaybeChars>() -> [u8; LEN] {
56 let mut chars = [0; LEN];
57
58 update_chars::<S>(&mut chars);
59
60 chars
61}
62
63const fn update_chars<S: MaybeChars>(mut chars: &mut [u8]) {
64 if let Some(value) = S::VALUE {
65 value.encode_utf8(chars);
66
67 let len = value.len_utf8();
68
69 let mut j = 0;
70 while j < len {
71 chars = chars.split_first_mut().unwrap().1;
72 j += 1;
73 }
74
75 update_chars::<S::Next>(chars);
76 }
77}