Skip to main content

cgp_field/types/
chars.rs

1use core::fmt::Display;
2use core::marker::PhantomData;
3
4use crate::traits::StaticFormat;
5
6/**
7    The `Chars` type, a.k.a. `ζ`, is used to represent _type-level_ list of
8    `Chars`s, which are equivalent to type-level strings.
9
10    `Chars` is a specialized version of [`Cons`](crate::types::Cons), with the
11    `Head` type being fixed to a _const-generic_ value of type `Chars`.
12    Similar to `Cons`, `Chars` is also parameterized by a `Tail` type, which is
13    expected to be either the next `Chars`, or [`Nil`](crate::types::Nil) to
14    represent the end of the string.
15
16    Instead of reusing `Cons`, we combine the use of `Cons` within `Chars` so
17    that its representation is more compact when shown in compiler error messages.
18    Similar to `Cons`, `Chars` is also shown as `ζ` to further improve its
19    readability.
20
21    We represent type-level strings as list of `Chars`s, because it is currently
22    not possible to use types like `String` or `&str` as const-generic parameters.
23    On the other hand, a single `Chars` can be used as a const-generic parameter,
24    and so we can workaround the limitation by combining a type-level list of
25    `Chars`s to represent a type-level string.
26
27    `Chars` is most often not used directly, but rather through the `Symbol!` macro,
28    which accepts a string literal and converts it into a list of `Chars`s.
29
30    ## Example
31
32    Given the following symbol definition:
33
34    ```rust,ignore
35    type Hello = Symbol!("hello");
36    ```
37
38    The following type would be generated:
39
40    ```rust,ignore
41    type Hello = Chars<'h', Chars<'e', Chars<'l', Chars<'l', Chars<'o', Nil>>>>>;
42    ```
43
44    which would be shown with the shortened representation as:
45
46    ```rust,ignore
47    type Hello = ζ<'h', ζ<'e', ζ<'l', ζ<'l', ζ<'o', ε>>>>>;
48    ```
49*/
50#[derive(Eq, PartialEq, Clone, Copy, Default)]
51pub struct ζ<const CHAR: char, Tail>(pub PhantomData<Tail>);
52
53pub use ζ as Chars;
54
55impl<const CHAR: char, Tail> Display for Chars<CHAR, Tail>
56where
57    Self: StaticFormat,
58{
59    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60        <Self as StaticFormat>::fmt(f)
61    }
62}