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
112
113
114
115
116
117
118
119
use rmpv::Value;
pub enum UiOption {
Rgb(bool),
ExtPopupmenu(bool),
ExtTabline(bool),
ExtCmdline(bool),
ExtWildmenu(bool),
ExtLinegrid(bool),
ExtHlstate(bool),
ExtMultigrid(bool),
ExtMessages(bool),
ExtTermcolors(bool),
}
impl UiOption {
fn to_value(&self) -> (Value, Value) {
let name_value = self.to_name_value();
(name_value.0.into(), name_value.1)
}
fn to_name_value(&self) -> (&'static str, Value) {
match *self {
Self::Rgb(val) => ("rgb", val.into()),
Self::ExtPopupmenu(val) => ("ext_popupmenu", val.into()),
Self::ExtTabline(val) => ("ext_tabline", val.into()),
Self::ExtCmdline(val) => ("ext_cmdline", val.into()),
Self::ExtWildmenu(val) => ("ext_wildmenu", val.into()),
Self::ExtLinegrid(val) => ("ext_linegrid", val.into()),
Self::ExtHlstate(val) => ("ext_hlstate", val.into()),
Self::ExtMultigrid(val) => ("ext_multigrid", val.into()),
Self::ExtMessages(val) => ("ext_messages", val.into()),
Self::ExtTermcolors(val) => ("ext_termcolors", val.into()),
}
}
}
#[derive(Default)]
pub struct UiAttachOptions {
options: Vec<(&'static str, UiOption)>,
}
macro_rules! ui_opt_setters {
($( $opt:ident as $set:ident );+ ;) => {
impl UiAttachOptions {
$(
pub fn $set(&mut self, val: bool) -> &mut Self {
self.set_option(UiOption::$opt(val));
self
}
)+
}
}
}
ui_opt_setters! (
Rgb as set_rgb;
ExtPopupmenu as set_popupmenu_external;
ExtTabline as set_tabline_external;
ExtCmdline as set_cmdline_external;
ExtWildmenu as set_wildmenu_external;
ExtLinegrid as set_linegrid_external;
ExtHlstate as set_hlstate_external;
ExtMultigrid as set_multigrid_external;
ExtMessages as set_messages_external;
ExtTermcolors as set_termcolors_external;
);
impl UiAttachOptions {
#[must_use]
pub fn new() -> UiAttachOptions {
UiAttachOptions {
options: Vec::new(),
}
}
fn set_option(&mut self, option: UiOption) {
let name = option.to_name_value();
let position = self.options.iter().position(|o| o.0 == name.0);
if let Some(position) = position {
self.options[position].1 = option;
} else {
self.options.push((name.0, option));
}
}
#[must_use]
pub fn to_value_map(&self) -> Value {
let map = self.options.iter().map(|o| o.1.to_value()).collect();
Value::Map(map)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ui_options() {
let value_map = UiAttachOptions::new()
.set_rgb(true)
.set_rgb(false)
.set_popupmenu_external(true)
.to_value_map();
assert_eq!(
Value::Map(vec![
("rgb".into(), false.into()),
("ext_popupmenu".into(), true.into()),
]),
value_map
);
}
}