shared/model_ui/screens_common/remote_multi_choice/multi_choice/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::screens_common::model::multi_choice::MultiChoice;
use crate::screens_common::model::string_index::StringIndex;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UiMultiChoice {
    pub options: Vec<UiMultiChoiceItem>,
    pub selected_index: Option<UiStringIndex>,
}

impl<T> From<&MultiChoice<T>> for UiMultiChoice
where
    T: ToString + Clone,
{
    fn from(value: &MultiChoice<T>) -> Self {
        // let mut drop_down_list = value.to_vec().into();

        let mut ui_multi_choice: UiMultiChoice = UiMultiChoice {
            options: multi_choice_options_to_ui_multi_select_choice(&value.options),
            selected_index: None,
        };

        if let Some(index) = value.selected {
            ui_multi_choice.selected_index = Some(index.into());
        }
        ui_multi_choice
    }
}

pub fn multi_choice_options_to_ui_multi_select_choice<T>(options: &[T]) -> Vec<UiMultiChoiceItem>
where
    T: ToString + Clone,
{
    options
        .iter()
        .enumerate()
        .map(|(index, inner_string)| UiMultiChoiceItem {
            hidden_uid: index.into(),
            user_facing_value: inner_string.to_string(),
        })
        .collect()
}

impl<T> From<&Vec<T>> for UiMultiChoice
where
    T: ToString,
{
    fn from(value: &Vec<T>) -> Self {
        let options = value
            .iter()
            .enumerate()
            .fold(vec![], |mut acc, (index, value)| {
                acc.push(UiMultiChoiceItem {
                    hidden_uid: UiStringIndex(index.to_string()),
                    user_facing_value: value.to_string(),
                });
                acc
            });

        let drop_down_list: UiMultiChoice = UiMultiChoice {
            options,
            selected_index: None,
        };

        drop_down_list
    }
}

/// DropDownList is made for a HTML Select object (hopefully generic enough to apply elsewhere)
/// The intention is to attach a uid value hidden from user to evey value that Rust can verify and
/// keep track of before it passes into the unknown of ffi
///
/// At the moment I'm letting the UI hold the selected state
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UiMultiChoiceItem {
    pub hidden_uid: UiStringIndex,
    pub user_facing_value: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct UiStringIndex(pub String);

impl From<StringIndex> for UiStringIndex {
    fn from(value: StringIndex) -> Self {
        UiStringIndex(value.0)
    }
}

impl From<usize> for UiStringIndex {
    fn from(value: usize) -> Self {
        UiStringIndex(value.to_string())
    }
}

impl UiStringIndex {
    pub fn to_bound_usize(&self, limit: usize) -> Result<usize, UiStringIndexErrors> {
        let maybe_index = self
            .0
            .parse::<usize>()
            .map_err(|_| UiStringIndexErrors::Parse)?;
        if maybe_index < limit {
            Ok(maybe_index)
        } else {
            Err(UiStringIndexErrors::OutOfBounds)
        }
    }
}
pub enum UiStringIndexErrors {
    Parse,
    OutOfBounds,
}