standout_render/tabular/traits.rs
1//! Traits for derive macro integration.
2//!
3//! These traits are implemented by the `#[derive(Tabular)]` and `#[derive(TabularRow)]`
4//! macros to enable type-safe tabular formatting.
5
6use super::TabularSpec;
7
8/// Trait for types that can generate a `TabularSpec`.
9///
10/// This trait is automatically implemented by `#[derive(Tabular)]`.
11///
12/// # Example
13///
14/// ```ignore
15/// use standout::tabular::{Tabular, TabularSpec};
16/// use serde::Serialize;
17///
18/// #[derive(Serialize, Tabular)]
19/// struct Task {
20/// #[col(width = 8, style = "muted")]
21/// id: String,
22///
23/// #[col(width = "fill")]
24/// title: String,
25///
26/// #[col(width = 12, align = "right")]
27/// status: String,
28/// }
29///
30/// // Use the generated spec
31/// let spec = Task::tabular_spec();
32/// ```
33pub trait Tabular {
34 /// Returns the `TabularSpec` for this type.
35 fn tabular_spec() -> TabularSpec;
36}
37
38/// Trait for types that can be converted to a row of strings.
39///
40/// This trait is automatically implemented by `#[derive(TabularRow)]`.
41/// It provides optimized row extraction without JSON serialization.
42///
43/// # Example
44///
45/// ```ignore
46/// use standout::tabular::TabularRow;
47///
48/// #[derive(TabularRow)]
49/// struct Task {
50/// id: String,
51/// title: String,
52/// status: String,
53/// }
54///
55/// let task = Task {
56/// id: "TSK-001".to_string(),
57/// title: "Implement feature".to_string(),
58/// status: "pending".to_string(),
59/// };
60///
61/// let row: Vec<String> = task.to_row();
62/// assert_eq!(row, vec!["TSK-001", "Implement feature", "pending"]);
63/// ```
64pub trait TabularRow {
65 /// Converts this instance to a row of string values.
66 fn to_row(&self) -> Vec<String>;
67}
68
69/// Trait for types that implement Display.
70pub trait TabularFieldDisplay {
71 fn to_tabular_cell(&self) -> String;
72}
73
74impl<T: std::fmt::Display> TabularFieldDisplay for T {
75 fn to_tabular_cell(&self) -> String {
76 self.to_string()
77 }
78}
79
80/// Trait for Option types.
81pub trait TabularFieldOption {
82 fn to_tabular_cell(&self) -> String;
83}
84
85impl<T: std::fmt::Display> TabularFieldOption for Option<T> {
86 fn to_tabular_cell(&self) -> String {
87 match self {
88 Some(v) => v.to_string(),
89 None => String::new(),
90 }
91 }
92}