1use rmpv::Value;
6
7pub enum UiOption {
8 Rgb(bool),
9 Override(bool),
10 ExtCmdline(bool),
11 ExtHlstate(bool),
12 ExtLinegrid(bool),
13 ExtMessages(bool),
14 ExtMultigrid(bool),
15 ExtPopupmenu(bool),
16 ExtTabline(bool),
17 ExtTermcolors(bool),
18 TermName(String),
19 TermColors(u64),
20 TermBackground(String),
21 StdinFd(u64),
22 StdinTty(bool),
23 StdoutTty(bool),
24 ExtWildmenu(bool),
25}
26
27impl UiOption {
28 fn to_value(&self) -> (Value, Value) {
29 let name_value = self.to_name_value();
30 (name_value.0.into(), name_value.1)
31 }
32
33 fn to_name_value(&self) -> (&'static str, Value) {
34 match self {
35 Self::Rgb(val) => ("rgb", (*val).into()),
36 Self::Override(val) => ("override", (*val).into()),
37 Self::ExtCmdline(val) => ("ext_cmdline", (*val).into()),
38 Self::ExtHlstate(val) => ("ext_hlstate", (*val).into()),
39 Self::ExtLinegrid(val) => ("ext_linegrid", (*val).into()),
40 Self::ExtMessages(val) => ("ext_messages", (*val).into()),
41 Self::ExtMultigrid(val) => ("ext_multigrid", (*val).into()),
42 Self::ExtPopupmenu(val) => ("ext_popupmenu", (*val).into()),
43 Self::ExtTabline(val) => ("ext_tabline", (*val).into()),
44 Self::ExtTermcolors(val) => ("ext_termcolors", (*val).into()),
45 Self::TermName(val) => ("term_name", val.as_str().into()),
46 Self::TermColors(val) => ("term_colors", (*val).into()),
47 Self::TermBackground(val) => ("term_background", val.as_str().into()),
48 Self::StdinFd(val) => ("stdin_fd", (*val).into()),
49 Self::StdinTty(val) => ("stdin_tty", (*val).into()),
50 Self::StdoutTty(val) => ("stdout_tty", (*val).into()),
51 Self::ExtWildmenu(val) => ("ext_wildmenu", (*val).into()),
52 }
53 }
54}
55
56#[derive(Default)]
57pub struct UiAttachOptions {
58 options: Vec<(&'static str, UiOption)>,
59}
60
61macro_rules! ui_opt_setters {
62 ($( $opt:ident as $set:ident($type:ty) );+ ;) => {
63 impl UiAttachOptions {
64 $(
65 pub fn $set(&mut self, val: $type) -> &mut Self {
66 self.set_option(UiOption::$opt(val.into()));
67 self
68 }
69 )+
70 }
71 }
72}
73
74ui_opt_setters! (
75
76 Rgb as set_rgb(bool);
77 Override as set_override(bool);
78 ExtCmdline as set_cmdline_external(bool);
79 ExtHlstate as set_hlstate_external(bool);
80 ExtLinegrid as set_linegrid_external(bool);
81 ExtMessages as set_messages_externa(bool);
82 ExtMultigrid as set_multigrid_external(bool);
83 ExtPopupmenu as set_popupmenu_external(bool);
84 ExtTabline as set_tabline_external(bool);
85 ExtTermcolors as set_termcolors_external(bool);
86 TermName as set_term_name(&str);
87 TermColors as set_term_colors(u64);
88 TermBackground as set_term_background(&str);
89 StdinFd as set_stdin_fd(u64);
90 StdinTty as set_stdin_tty(bool);
91 StdoutTty as set_stdout_tty(bool);
92 ExtWildmenu as set_wildmenu_external(bool);
93);
94
95impl UiAttachOptions {
96 #[must_use]
97 pub fn new() -> UiAttachOptions {
98 UiAttachOptions {
99 options: Vec::new(),
100 }
101 }
102
103 fn set_option(&mut self, option: UiOption) {
104 let name = option.to_name_value();
105 let position = self.options.iter().position(|o| o.0 == name.0);
106
107 if let Some(position) = position {
108 self.options[position].1 = option;
109 } else {
110 self.options.push((name.0, option));
111 }
112 }
113
114 #[must_use]
115 pub fn to_value_map(&self) -> Value {
116 let map = self.options.iter().map(|o| o.1.to_value()).collect();
117 Value::Map(map)
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_ui_options() {
127 let value_map = UiAttachOptions::new()
128 .set_rgb(true)
129 .set_rgb(false)
130 .set_popupmenu_external(true)
131 .to_value_map();
132
133 assert_eq!(
134 Value::Map(vec![
135 ("rgb".into(), false.into()),
136 ("ext_popupmenu".into(), true.into()),
137 ]),
138 value_map
139 );
140 }
141}