cli_table_derive/
table.rs1use proc_macro2::TokenStream;
2use quote::{quote, quote_spanned};
3use syn::{DeriveInput, Result};
4
5use crate::context::Context;
6
7pub fn table(input: DeriveInput) -> Result<TokenStream> {
8 let context = Context::new(&input)?;
10
11 let name = context.container.name;
13
14 let cli_table = &context.container.crate_name;
16
17 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
19
20 let mut field_titles = Vec::new();
21 let mut field_rows = Vec::new();
22
23 for field in context.fields.into_iter() {
24 field_titles.push(field.title);
25
26 let ident = field.ident;
27 let justify = field.justify;
28 let align = field.align;
29 let color = field.color;
30 let bold = field.bold;
31 let display_fn = field.display_fn;
32 let customize_fn = field.customize_fn;
33 let span = field.span;
34
35 let cell = match display_fn {
36 None => quote_spanned! {span=>
37 &self. #ident
38 },
39 Some(display_fn) => {
40 let span = display_fn.span();
41 quote_spanned! {span=>
42 #display_fn (&self. #ident)
43 }
44 }
45 };
46
47 let mut row = quote_spanned! {span=>
48 #cli_table ::Cell::cell(#cell)
49 };
50
51 if let Some(justify) = justify {
52 row = quote_spanned! {span=>
53 #row .justify(#justify)
54 };
55 }
56
57 if let Some(align) = align {
58 row = quote_spanned! {span=>
59 #row .align(#align)
60 };
61 }
62
63 if let Some(color) = color {
64 row = quote_spanned! {span=>
65 #cli_table ::Style::foreground_color(#row, ::core::convert::From::from(#color))
66 };
67 }
68
69 if let Some(bold) = bold {
70 row = quote_spanned! {span=>
71 #cli_table ::Style::bold(#row, #bold)
72 };
73 }
74
75 if let Some(customize_fn) = customize_fn {
76 row = quote_spanned! {span=>
77 #customize_fn (#row, &self. #ident)
78 };
79 }
80
81 field_rows.push(row);
82 }
83
84 Ok(quote! {
86 #[automatically_derived]
87 impl #impl_generics #cli_table ::Title for #name #ty_generics # where_clause{
88 fn title() -> #cli_table ::RowStruct {
89 let title: ::std::vec::Vec<#cli_table ::CellStruct> = ::std::vec![
90 #(#cli_table ::Style::bold(#cli_table ::Cell::cell(#field_titles), true),)*
91 ];
92
93 #cli_table ::Row::row(title)
94 }
95 }
96
97 #[automatically_derived]
98 impl #impl_generics #cli_table ::Row for & #name #ty_generics # where_clause{
99 fn row(self) -> #cli_table ::RowStruct {
100 let row: ::std::vec::Vec<#cli_table ::CellStruct> = ::std::vec![
101 #(#field_rows,)*
102 ];
103
104 #cli_table ::Row::row(row)
105 }
106 }
107
108 #[automatically_derived]
109 impl #impl_generics #cli_table ::Row for #name #ty_generics # where_clause{
110 fn row(self) -> #cli_table ::RowStruct {
111 #cli_table ::Row::row(&self)
112 }
113 }
114 })
115}