返回 CodeWhale
option.rs
根目录 / crates / tui / src / tui / settings_picker / option.rs
1 //! Declarative setting-option contract shared by settings pickers.
2 //!
3 //! Every picker row declares current/default/effective values, availability,
4 //! help/detail copy, and optional per-row actions. The option list is pure
5 //! data: hosts map [`super::PickerNavResult`] into their own preview/commit
6 //! actions, so a single option list can drive live preview without mutating
7 //! commit policy.
8
9 use std::borrow::Cow;
10
11 /// Triple of values a setting exposes for truthful chrome.
12 #[derive(Debug, Clone, PartialEq, Eq)]
13 pub struct SettingValues<T> {
14 pub current: T,
15 pub default: T,
16 pub effective: T,
17 }
18
19 impl<T> SettingValues<T> {
20 #[must_use]
21 pub const fn new(current: T, default: T, effective: T) -> Self {
22 Self {
23 current,
24 default,
25 effective,
26 }
27 }
28 }
29
30 /// Whether a row can be selected / committed.
31 #[derive(Debug, Clone, PartialEq, Eq)]
32 pub enum SettingAvailability {
33 Available,
34 #[allow(dead_code)] // disabled rows with reasons for model/provider pickers (TUI-DOG-009)
35 Disabled {
36 reason: Cow<'static, str>,
37 },
38 }
39
40 impl SettingAvailability {
41 #[must_use]
42 pub fn is_available(&self) -> bool {
43 matches!(self, Self::Available)
44 }
45
46 #[must_use]
47 #[allow(dead_code)] // reason chrome for disabled rows (TUI-DOG-009)
48 pub fn disabled_reason(&self) -> Option<&str> {
49 match self {
50 Self::Available => None,
51 Self::Disabled { reason } => Some(reason.as_ref()),
52 }
53 }
54 }
55
56 /// Optional secondary action attached to a row (toggle, refresh, …).
57 #[derive(Debug, Clone, PartialEq, Eq)]
58 pub struct SettingItemAction {
59 pub id: Cow<'static, str>,
60 pub label: Cow<'static, str>,
61 }
62
63 /// One selectable option in a settings picker.
64 #[derive(Debug, Clone, PartialEq, Eq)]
65 pub struct SettingOption {
66 pub id: Cow<'static, str>,
67 pub label: Cow<'static, str>,
68 /// Short secondary line shown in the list (tagline / summary).
69 pub summary: Cow<'static, str>,
70 /// Longer help shown in the detail pane.
71 pub detail: Cow<'static, str>,
72 pub help: Cow<'static, str>,
73 pub values: SettingValues<Cow<'static, str>>,
74 pub availability: SettingAvailability,
75 pub tab: Cow<'static, str>,
76 pub action: Option<SettingItemAction>,
77 /// When true, narrow terminals drop the detail pane and keep the list.
78 pub prefer_list_when_narrow: bool,
79 }
80
81 impl SettingOption {
82 #[must_use]
83 pub fn builder(
84 id: impl Into<Cow<'static, str>>,
85 label: impl Into<Cow<'static, str>>,
86 ) -> SettingOptionBuilder {
87 SettingOptionBuilder {
88 id: id.into(),
89 label: label.into(),
90 summary: Cow::Borrowed(""),
91 detail: Cow::Borrowed(""),
92 help: Cow::Borrowed(""),
93 values: SettingValues::new(Cow::Borrowed(""), Cow::Borrowed(""), Cow::Borrowed("")),
94 availability: SettingAvailability::Available,
95 tab: Cow::Borrowed("all"),
96 action: None,
97 prefer_list_when_narrow: true,
98 }
99 }
100 }
101
102 /// Fluent constructor for [`SettingOption`].
103 #[derive(Debug, Clone)]
104 pub struct SettingOptionBuilder {
105 id: Cow<'static, str>,
106 label: Cow<'static, str>,
107 summary: Cow<'static, str>,
108 detail: Cow<'static, str>,
109 help: Cow<'static, str>,
110 values: SettingValues<Cow<'static, str>>,
111 availability: SettingAvailability,
112 tab: Cow<'static, str>,
113 action: Option<SettingItemAction>,
114 prefer_list_when_narrow: bool,
115 }
116
117 impl SettingOptionBuilder {
118 #[must_use]
119 pub fn summary(mut self, summary: impl Into<Cow<'static, str>>) -> Self {
120 self.summary = summary.into();
121 self
122 }
123
124 #[must_use]
125 pub fn detail(mut self, detail: impl Into<Cow<'static, str>>) -> Self {
126 self.detail = detail.into();
127 self
128 }
129
130 #[must_use]
131 pub fn help(mut self, help: impl Into<Cow<'static, str>>) -> Self {
132 self.help = help.into();
133 self
134 }
135
136 #[must_use]
137 pub fn values(mut self, values: SettingValues<Cow<'static, str>>) -> Self {
138 self.values = values;
139 self
140 }
141
142 #[must_use]
143 pub fn availability(mut self, availability: SettingAvailability) -> Self {
144 self.availability = availability;
145 self
146 }
147
148 #[must_use]
149 pub fn tab(mut self, tab: impl Into<Cow<'static, str>>) -> Self {
150 self.tab = tab.into();
151 self
152 }
153
154 #[must_use]
155 #[allow(dead_code)] // per-row secondary actions for model/provider hosts (TUI-DOG-009)
156 pub fn action(mut self, action: SettingItemAction) -> Self {
157 self.action = Some(action);
158 self
159 }
160
161 #[must_use]
162 pub fn prefer_list_when_narrow(mut self, prefer: bool) -> Self {
163 self.prefer_list_when_narrow = prefer;
164 self
165 }
166
167 #[must_use]
168 pub fn build(self) -> SettingOption {
169 SettingOption {
170 id: self.id,
171 label: self.label,
172 summary: self.summary,
173 detail: self.detail,
174 help: self.help,
175 values: self.values,
176 availability: self.availability,
177 tab: self.tab,
178 action: self.action,
179 prefer_list_when_narrow: self.prefer_list_when_narrow,
180 }
181 }
182 }
183
183 lines RUST