1use crate::{
2 grid::config::{ColoredConfig, CompactMultilineConfig, Entity},
3 settings::{CellOption, TableOption},
4};
5
6/// `AlignmentStrategy` is a responsible for a flow how we apply an alignment.
7/// It mostly matters for multiline strings.
8///
9/// # Examples
10///
11/// ```
12/// use tabled::{
13/// Table,
14/// settings::{
15/// Style, Modify, Alignment, object::Segment,
16/// formatting::{AlignmentStrategy, TrimStrategy}
17/// }
18/// };
19///
20/// // sample_from: https://opensource.adobe.com/Spry/samples/data_region/JSONDataSetSample.html
21/// let json = r#"
22/// {
23/// "id": "0001",
24/// "type": "donut",
25/// "name": "Cake",
26/// "ppu": 0.55,
27/// "batters": {
28/// "batter": [
29/// { "id": "1001", "type": "Regular" },
30/// { "id": "1002", "type": "Chocolate" },
31/// ]
32/// },
33/// "topping": [
34/// { "id": "5001", "type": "None" },
35/// { "id": "5006", "type": "Chocolate with Sprinkles" },
36/// { "id": "5003", "type": "Chocolate" },
37/// { "id": "5004", "type": "Maple" }
38/// ]
39/// }"#;
40///
41/// let mut table = Table::new(&[json]);
42/// table
43/// .with(Style::modern())
44/// .with(Modify::new(Segment::all()).with(Alignment::right()))
45/// .with(Modify::new(Segment::all()).with(TrimStrategy::None));
46///
47/// println!("{}", table);
48///
49/// assert_eq!(
50/// format!("\n{}", table),
51/// r#"
52/// ┌───────────────────────────────────────────────────────────────┐
53/// │ &str │
54/// ├───────────────────────────────────────────────────────────────┤
55/// │ │
56/// │ { │
57/// │ "id": "0001", │
58/// │ "type": "donut", │
59/// │ "name": "Cake", │
60/// │ "ppu": 0.55, │
61/// │ "batters": { │
62/// │ "batter": [ │
63/// │ { "id": "1001", "type": "Regular" }, │
64/// │ { "id": "1002", "type": "Chocolate" }, │
65/// │ ] │
66/// │ }, │
67/// │ "topping": [ │
68/// │ { "id": "5001", "type": "None" }, │
69/// │ { "id": "5006", "type": "Chocolate with Sprinkles" }, │
70/// │ { "id": "5003", "type": "Chocolate" }, │
71/// │ { "id": "5004", "type": "Maple" } │
72/// │ ] │
73/// │ } │
74/// └───────────────────────────────────────────────────────────────┘"#);
75///
76/// table
77/// .with(Modify::new(Segment::all()).with(AlignmentStrategy::PerCell))
78/// .with(Modify::new(Segment::all()).with(TrimStrategy::Horizontal));
79///
80/// assert_eq!(
81/// format!("\n{}", table),
82/// r#"
83/// ┌───────────────────────────────────────────────────────────────┐
84/// │ &str │
85/// ├───────────────────────────────────────────────────────────────┤
86/// │ │
87/// │ { │
88/// │ "id": "0001", │
89/// │ "type": "donut", │
90/// │ "name": "Cake", │
91/// │ "ppu": 0.55, │
92/// │ "batters": { │
93/// │ "batter": [ │
94/// │ { "id": "1001", "type": "Regular" }, │
95/// │ { "id": "1002", "type": "Chocolate" }, │
96/// │ ] │
97/// │ }, │
98/// │ "topping": [ │
99/// │ { "id": "5001", "type": "None" }, │
100/// │ { "id": "5006", "type": "Chocolate with Sprinkles" }, │
101/// │ { "id": "5003", "type": "Chocolate" }, │
102/// │ { "id": "5004", "type": "Maple" } │
103/// │ ] │
104/// │ } │
105/// └───────────────────────────────────────────────────────────────┘"#);
106///
107/// table.with(Modify::new(Segment::all()).with(AlignmentStrategy::PerLine));
108///
109/// assert_eq!(
110/// format!("\n{}", table),
111/// r#"
112/// ┌───────────────────────────────────────────────────────────────┐
113/// │ &str │
114/// ├───────────────────────────────────────────────────────────────┤
115/// │ │
116/// │ { │
117/// │ "id": "0001", │
118/// │ "type": "donut", │
119/// │ "name": "Cake", │
120/// │ "ppu": 0.55, │
121/// │ "batters": { │
122/// │ "batter": [ │
123/// │ { "id": "1001", "type": "Regular" }, │
124/// │ { "id": "1002", "type": "Chocolate" }, │
125/// │ ] │
126/// │ }, │
127/// │ "topping": [ │
128/// │ { "id": "5001", "type": "None" }, │
129/// │ { "id": "5006", "type": "Chocolate with Sprinkles" }, │
130/// │ { "id": "5003", "type": "Chocolate" }, │
131/// │ { "id": "5004", "type": "Maple" } │
132/// │ ] │
133/// │ } │
134/// └───────────────────────────────────────────────────────────────┘"#);
135/// ```
136#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
137pub enum AlignmentStrategy {
138 /// Apply alignment for cell content as a whole.
139 PerCell,
140 /// Apply alignment for each line of a cell content as a whole.
141 PerLine,
142}
143
144impl<R> CellOption<R, ColoredConfig> for AlignmentStrategy {
145 fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
146 let mut formatting: Formatting = *cfg.get_formatting(entity);
147 match &self {
148 AlignmentStrategy::PerCell => formatting.allow_lines_alignment = false,
149 AlignmentStrategy::PerLine => formatting.allow_lines_alignment = true,
150 }
151
152 cfg.set_formatting(entity, formatting);
153 }
154}
155
156impl<R, D> TableOption<R, D, ColoredConfig> for AlignmentStrategy {
157 fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
158 <Self as CellOption<R, ColoredConfig>>::change(self, records, cfg, Entity::Global)
159 }
160}
161
162impl<R, D> TableOption<R, D, CompactMultilineConfig> for AlignmentStrategy {
163 fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
164 let mut f: Formatting = cfg.get_formatting();
165 match &self {
166 AlignmentStrategy::PerCell => f.allow_lines_alignment = false,
167 AlignmentStrategy::PerLine => f.allow_lines_alignment = true,
168 }
169
170 *cfg = cfg.set_formatting(f);
171 }
172}
173