1#[macro_export]
12macro_rules! impl_text_input_with_stringops {
13 ($text_input: ident, $type_name: literal, $type: ty) => {
14 impl_text_input_with_stringops!(
15 $text_input,
16 |_e| structform::ParseError::InvalidFormat {
17 required_type: $type_name.to_string()
18 },
19 $type
20 );
21 };
22 ($text_input: ident, $type: ty) => {
23 impl_text_input_with_stringops!(
24 $text_input,
25 |e| structform::ParseError::FromStrError(e.to_string()),
26 $type
27 );
28 };
29 ($text_input: ident, $handle_error: expr, $type: ty) => {
30 impl structform::ParseAndFormat<$type> for $text_input<$type> {
31 fn parse(value: &str) -> Result<$type, structform::ParseError> {
32 let trimmed = value.trim();
33 if trimmed.is_empty() {
34 Err(structform::ParseError::Required)
35 } else {
36 trimmed.parse::<$type>().map_err($handle_error)
37 }
38 }
39
40 fn format(value: &$type) -> String {
41 value.to_string()
42 }
43 }
44
45 impl structform::ParseAndFormat<Option<$type>> for $text_input<Option<$type>> {
46 fn parse(value: &str) -> Result<Option<$type>, structform::ParseError> {
47 let trimmed = value.trim();
48 if trimmed.is_empty() {
49 Ok(None)
50 } else {
51 trimmed
52 .parse::<$type>()
53 .map(Option::Some)
54 .map_err(|e| structform::ParseError::FromStrError(e.to_string()))
55 }
56 }
57
58 fn format(value: &Option<$type>) -> String {
59 match value {
60 None => "".to_string(),
61 Some(inner) => inner.to_string(),
62 }
63 }
64 }
65 };
66}
67
68#[macro_export]
79macro_rules! impl_vec_text_input_with_stringops {
80 ($text_input: ident, $type_name: literal, $type: ty) => {
81 impl_vec_text_input_with_stringops!(
82 $text_input,
83 |_e| structform::ParseError::InvalidFormat {
84 required_type: $type_name.to_string()
85 },
86 $type
87 );
88 };
89 ($text_input: ident, $type: ty) => {
90 impl_vec_text_input_with_stringops!(
91 $text_input,
92 |e| structform::ParseError::FromStrError(e.to_string()),
93 $type
94 );
95 };
96 ($text_input: ident, $handle_error: expr, $type: ty) => {
97 impl structform::ParseAndFormat<Vec<$type>> for $text_input<Vec<$type>> {
98 fn parse(value: &str) -> Result<Vec<$type>, structform::ParseError> {
99 value
100 .trim()
101 .split(',')
102 .map(|s| s.trim())
103 .filter(|s| !s.is_empty())
104 .map(|trimmed| trimmed.parse::<$type>().map_err($handle_error))
105 .collect()
106 }
107
108 fn format(value: &Vec<$type>) -> String {
109 value
110 .iter()
111 .map(|value| value.to_string())
112 .collect::<Vec<_>>()
113 .join(", ")
114 }
115 }
116 };
117}