tabled/derive/
mod.rs

1//! Module contains a list of helpers for work with derive.
2
3pub mod display;
4
5/// A derive macro to implement a [`Tabled`] trait.
6///
7/// The macro available only when `derive` feature in turned on (and it is by default).
8///
9/// ```
10/// use tabled::Tabled;
11///
12/// #[derive(Tabled)]
13/// struct SomeType {
14///     field0: &'static str,
15///     field1: String,
16///     field2: usize,
17/// }
18/// ```
19///
20/// To be able to use the derive each field must implement `std::fmt::Display`.\
21/// The following example will cause an error because of that.
22///
23/// ```,compile_fail
24/// use tabled::Tabled;
25///
26/// #[derive(Tabled)]
27/// struct SomeType {
28///     field1: Vec<usize>,
29/// }
30/// ```
31///
32/// Bellow you'll find available options for it.
33///
34/// ## Rename a column name
35///
36/// You can use a `#[tabled(rename = "")]` attribute to override a column name.
37///
38/// ```
39/// use tabled::Tabled;
40///
41/// #[derive(Tabled)]
42/// struct Person {
43///     #[tabled(rename = "Name")]
44///     first_name: String,
45///     #[tabled(rename = "Surname")]
46///     last_name: String,
47/// }
48/// ```
49///
50/// ## Hide a column
51///
52/// You can mark fields as hidden in which case they fill be ignored and not be present on a sheet.
53///
54/// ```
55/// use tabled::Tabled;
56///
57/// #[derive(Tabled)]
58/// struct Person {
59///    id: u8,
60///    #[tabled(skip)]
61///    number: String,
62///    name: String,
63/// }
64/// ```
65///
66/// ## Set column order
67///
68/// You can change the order in which they will be displayed in table.
69///
70/// ```
71/// use tabled::Tabled;
72///
73/// #[derive(Tabled)]
74/// struct Person {
75///    id: u8,
76///    #[tabled(order = 0)]
77///    number: String,
78///    #[tabled(order = 1)]
79///    name: String,
80/// }
81/// ```
82///
83/// ## Format fields
84///
85/// Using `#[derive(Tabled)]` is possible only when all fields implement a `Display` trait.\
86/// However, this may be not convinient for example when a field uses the `Option` type.\
87/// There's 2 common ways how to solve this:
88///
89/// - Implement `Tabled` trait manually for a type.
90/// - Wrap `Option` to something like `DisplayedOption<T>(Option<T>)` and implement a Display trait for it.
91///
92/// But, it's not quite convient either.
93///
94/// So alternatively, we provide the next solutions.
95///
96/// - Use the `#[tabled(display = "func")]` - attribute to set a display function.
97/// - Use the `#[tabled(format = "{}")]` - attribute to format field.
98///
99/// ### `#[tabled(display)]`
100///
101/// A poverfull helper, the set function must have a first argument as a reference to a field.\
102/// It supports custom arguments as well (including `self`).
103///
104/// You can set it right on the whole type,\
105/// In which case all fields which are matching a set type will be using the given function.
106///
107/// We also provide a set of commonly used function for your types.\
108/// You can find them in [`tabled::derive::display`].
109///
110/// ```
111/// use tabled::Tabled;
112/// use tabled::derive::display;
113///
114/// #[derive(Tabled)]
115/// #[tabled(display(i64, "display_i64"))]
116/// pub struct Record {
117///     pub id: i64,
118///     #[tabled(display("display::option", "unvalidated"))]
119///     pub valid: Option<bool>,
120///     #[tabled(display("display_private", self))]
121///     pub private: (),
122/// }
123///
124/// fn display_private(_: &(), rec: &Record) -> String {
125///     todo!()
126/// }
127///
128/// fn display_i64(val: &i64) -> String {
129///     todo!()
130/// }
131/// ```
132///
133/// ### `#[tabled(format)]`
134///
135/// An analogue to [`format!`], which can be used right on the field.\
136///
137/// ```
138/// use tabled::Tabled;
139///
140/// #[derive(Tabled)]
141/// struct Record {
142///     #[tabled(skip)]
143///     id: u8,
144///     #[tabled(format("{}.{}-{}", self.id, self.name, 123))]
145///     name: String,
146/// }
147/// ```
148///
149/// ## Format headers
150///
151/// Beside `#[tabled(rename = "")]` you can change a format of a column name using\
152/// `#[tabled(rename_all = "UPPERCASE")]`.
153///
154/// ```
155/// use tabled::Tabled;
156///
157/// #[derive(Tabled)]
158/// #[tabled(rename_all = "CamelCase")]
159/// struct Person {
160///     id: u8,
161///     number: String,
162///     name: String,
163///     #[tabled(rename_all = "snake_case")]
164///     middle_name: String,
165/// }
166/// ```
167///
168/// ## Embeding a field
169///
170/// You can inline a field or a variant if it implements `Tabled` trait\
171/// using `#[tabled(inline)]`.
172/// You can also set a prefix for inlined elements by given it as a argument\
173/// `#[tabled(inline("::::"))]`.
174///
175/// ```
176/// use tabled::Tabled;
177///
178/// #[derive(Tabled)]
179/// struct Person {
180///     id: u8,
181///     name: String,
182///     #[tabled(inline)]
183///     ed: Education,
184/// }
185///
186/// #[derive(Tabled)]
187/// struct Education {
188///     uni: String,
189///     graduated: bool,
190/// }
191/// ```
192///
193/// And it works for enums as well.
194///
195/// ```
196/// use tabled::Tabled;
197///
198/// #[derive(Tabled)]
199/// enum Vehicle {
200///     #[tabled(inline("Auto::"))]
201///     Auto {
202///         model: String,
203///         engine: String,
204///     },
205///     #[tabled(inline)]
206///     Bikecycle(
207///         String,
208///         #[tabled(inline)] Bike,
209///     ),
210/// }
211///
212/// #[derive(Tabled)]
213/// struct Bike {
214///     brand: &'static str,
215///     price: f32,
216/// }
217/// ```
218///
219/// [`tabled::derive::display`]: crate::tabled::derive::display
220pub use tabled_derive::Tabled;