cgp_field/types/field.rs
1use core::fmt::Debug;
2use core::marker::PhantomData;
3
4/**
5 The `Field` type, a.k.a. `ω`, is used to represent a _named_ field entry
6 within a product type or a sum type.
7
8 `Field` is parameterized by a phantom `Tag` type, which is used to represent
9 the field name as type. Typically, this would either be a type-level string
10 such as `Symbol!("name")`, or a type-level index such as `Index<0>`.
11 Aside from that, `Field` is essentially a wrapper around `Value`.
12
13 `Field` is mainly used within the derived [`HasFields`](crate::traits::HasFields)
14 implementations, to include the field name in the generic product or sum
15 representation of the given struct or enum.
16
17 `Field` is also shown as `ω` to improve the readability of compiler error
18 messages. It is mainly useful when the type from `HasFields::Fields` is shown,
19 which would contain a lot of `Field`s and tend to take up a lot of screen space
20 to read.
21
22 ## Example
23
24 Given the following struct definition:
25
26 ```rust,ignore
27 #[derive(HasFields)]
28 pub struct MyContext {
29 pub name: String,
30 pub age: u8,
31 }
32 ```
33
34 The following `HasFields` implementation would be generated:
35
36 ```rust,ignore
37 impl HasFields for MyContext {
38 type Fields = Product![Field<Symbol!("name"), String>, Field<Symbol!("age"), u8>];
39 }
40 ```
41
42 which would be shown with the shortened representation as:
43
44 ```rust,ignore
45 impl HasFields for MyContext {
46 type Fields =
47 π<ω<Symbol!("name"), String>,
48 π<ω<Symbol!("age"), u8>,
49 ε>>;
50 }
51 ```
52*/
53pub struct ω<Tag, Value> {
54 pub value: Value,
55 pub phantom: PhantomData<Tag>,
56}
57
58pub use ω as Field;
59
60impl<Tag, Value> From<Value> for Field<Tag, Value> {
61 fn from(value: Value) -> Self {
62 Self {
63 value,
64 phantom: PhantomData,
65 }
66 }
67}
68
69impl<Tag, Value> Debug for Field<Tag, Value>
70where
71 Value: Debug,
72{
73 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
74 self.value.fmt(f)
75 }
76}
77
78impl<Tag, Value> PartialEq for Field<Tag, Value>
79where
80 Value: PartialEq,
81{
82 fn eq(&self, other: &Self) -> bool {
83 self.value.eq(&other.value)
84 }
85}
86
87impl<Tag, Value> Eq for Field<Tag, Value>
88where
89 Value: Eq,
90{
91 fn assert_receiver_is_total_eq(&self) {
92 self.value.assert_receiver_is_total_eq()
93 }
94}