1use crate::EzCptIds;
2use Direction::{Horizontal, Vertical};
3use FormFieldType::{CheckBox, Date, DateTime, Number, Password, Range, Select, Text, Time};
4use ratatui::layout::{Constraint, Direction};
5use std::cmp::max;
6use std::fmt::Display;
7
8#[derive(Debug, Eq, PartialEq, Clone)]
10pub enum FormFieldType {
11 Text {},
13 Password {},
15 CheckBox {},
17 Number {},
19 Range {},
21 DateTime {},
23 Date {},
25 Time {},
27 Select {
29 values: Vec<String>,
31 default: usize,
33 },
34}
35#[derive(Debug, Eq, PartialEq, Clone)]
37pub enum DateTimeConfig {
38 Date,
40 Time,
42 DateTime,
44}
45
46#[derive(Debug, Clone)]
48pub struct FormField<FID>
49where
50 FID: EzCptIds,
51{
52 id: FID,
54 name: String,
56 field_type: FormFieldType,
58 constraint: Option<Constraint>,
60}
61
62impl<FID> FormField<FID>
63where
64 FID: EzCptIds,
65{
66 pub fn with_name(id: FID, name: String, field_type: FormFieldType) -> Self {
68 Self {
69 id,
70 name,
71 field_type,
72 constraint: None,
73 }
74 }
75}
76
77impl<FID> FormField<FID>
78where
79 FID: EzCptIds + Display,
80{
81 pub fn new(id: FID, field_type: FormFieldType) -> Self {
83 let name = id.to_string();
84 Self {
85 id,
86 name,
87 field_type,
88 constraint: None,
89 }
90 }
91}
92impl<FID> FormField<FID>
93where
94 FID: EzCptIds,
95{
96 pub fn id(&self) -> &FID {
98 &self.id
99 }
100 pub fn name(&self) -> String {
102 self.name.to_string()
103 }
104
105 pub fn field_type(&self) -> &FormFieldType {
107 &self.field_type
108 }
109
110 #[allow(dead_code)] pub(crate) fn as_constraint(&self, direction: Direction, _count: usize) -> Constraint {
112 if let Some(constraint) = self.constraint {
113 constraint
114 } else {
115 let name_length = u16::try_from(self.name.len()).unwrap_or_default();
116 match (direction, &self.field_type) {
117 (Horizontal, Select { values, .. }) => {
118 let width: u16 = values
119 .iter()
120 .map(|s| u16::try_from(s.len()).unwrap_or_default())
121 .sum();
122 Constraint::Min(width + 2)
123 }
124 (Vertical, Select { values, .. }) => {
125 Constraint::Length(u16::try_from(values.len()).unwrap_or_default() + 2)
126 }
127
128 (Horizontal, Text {} | Password {} | Number {} | Range {} | Time {}) => {
129 Constraint::Min(name_length)
130 }
131 (Vertical, Text {} | Password {} | Number {} | Range {} | Time {}) => {
132 Constraint::Length(3)
133 }
134
135 (Horizontal, CheckBox {}) => Constraint::Max(max(name_length + 2, 5)),
136 (Vertical, CheckBox {}) => Constraint::Length(3),
137
138 (Horizontal, Date {} | DateTime {}) => Constraint::Min(max(name_length + 2, 20)),
139 (Vertical, Date {}) => Constraint::Length(9),
140 (Vertical, DateTime {}) => Constraint::Length(10),
141 }
142 }
143 }
144}