1use std::{collections::HashMap, fmt::Display, str::FromStr};
2
3pub mod button;
4mod drop_image_file;
5pub mod form;
6mod image_upload;
7mod input;
8pub mod login;
9mod popup;
10pub mod resource_table;
11mod search_panel;
12mod select;
13mod select_search;
14mod spinner;
15mod switch;
16mod tabs;
17mod with_loader;
18
19pub use {
20 button::{Button, ButtonColor, ButtonVariant, TableButton},
21 drop_image_file::{DropImageFile, DropImageFileParams, image_as_uri, name_to_mime},
22 image_upload::ImageUpload,
23 input::{Input, InputWithButton, InputWithButtonParams, ListInput},
24 popup::{Popup, PopupOnHover, PopupParams},
25 search_panel::{SearchPanel, SearchPanelParams, SearchResult},
26 select::{DictSelect, MultiDropDown, MultiDropDownParams, MultiSelect, Select},
27 select_search::{SelectSearch, SelectSearchParams},
28 spinner::Spinner,
29 switch::{Switch, SwitchParams},
30 tabs::{Tab, Tabs, TabsContent, TabsContentMapped, TabsHeader, TabsParams},
31 with_loader::{WithLoader, with_loader},
32};
33
34pub type ValidationErrors = HashMap<String, String>;
35
36pub fn parse<T>(value: String, field: &'static str, errors: &mut ValidationErrors) -> Option<T>
37where
38 T: FromStr,
39 <T as FromStr>::Err: Display,
40{
41 match value.parse() {
42 Ok(price) => Some(price),
43 Err(err) => {
44 errors.insert(field.to_string(), err.to_string());
45 None
46 }
47 }
48}
49
50pub fn nonify(value: String) -> Option<String> {
51 Some(value).filter(|v| !v.trim().is_empty())
52}
53
54pub fn parse_optional<T>(
55 value: String,
56 field: &'static str,
57 errors: &mut ValidationErrors,
58) -> Option<T>
59where
60 T: FromStr,
61 <T as FromStr>::Err: Display,
62{
63 match nonify(value) {
64 Some(value) => parse(value, field, errors),
65 None => None,
66 }
67}