use super::*;
impl Settings {
pub(in crate::lookout::app) fn new(snapshot: SettingsSnapshot) -> Self {
Self {
snapshot,
folded: BTreeSet::new(),
view: Viewport::new(),
pending: None,
dog_trees: BTreeMap::new(),
}
}
#[must_use]
pub fn pending(&self) -> Option<SettingsPrompt<'_>> {
match &self.pending {
Some(
Pending::Armed { text, .. }
| Pending::DogArmed { text, .. }
| Pending::DogTuneArmed { text, .. }
| Pending::DogSectionArmed { text, .. }
| Pending::DogEnvArmed { text, .. },
) => Some(SettingsPrompt { text, sent: false }),
Some(Pending::Sent { text, .. }) => Some(SettingsPrompt { text, sent: true }),
Some(Pending::Typing { .. } | Pending::TypingEnv { .. }) | None => None,
}
}
pub(in crate::lookout::app) fn resolve(&mut self, ticket: u64) -> bool {
let mine = matches!(
self.pending,
Some(Pending::Sent { ticket: waiting, .. }) if waiting == ticket
);
if mine {
self.pending = None;
}
mine
}
pub(in crate::lookout::app) fn is_armed(&self) -> bool {
matches!(
self.pending,
Some(
Pending::Armed { .. }
| Pending::DogArmed { .. }
| Pending::DogTuneArmed { .. }
| Pending::DogSectionArmed { .. }
| Pending::DogEnvArmed { .. }
)
)
}
#[must_use]
pub fn env_typing(&self) -> Option<(&str, &KeyValues)> {
match &self.pending {
Some(Pending::TypingEnv { dog, editor }) => Some((dog.as_str(), editor)),
_ => None,
}
}
#[must_use]
pub fn typing(&self) -> Option<(String, &TextBox)> {
match &self.pending {
Some(Pending::Typing { target, buffer }) => Some((target.label(), buffer)),
_ => None,
}
}
#[must_use]
pub fn typing_is_secret(&self) -> bool {
matches!(
&self.pending,
Some(Pending::Typing {
target: Target::DogValue { secret: true, .. },
..
})
)
}
pub(in crate::lookout::app) fn next_candidate(&self, field: &Field) -> Option<String> {
let armed_here = match &self.pending {
Some(Pending::Armed {
edit: SettingEdit::Set { value, .. },
..
}) if self.armed_for(field) => Some(value.clone()),
_ => None,
};
let base = armed_here
.or_else(|| {
self.snapshot.file_value(&field.key).map(|value| {
value
.as_str()
.map_or_else(|| value.to_string(), str::to_owned)
})
})
.or_else(|| {
field.default_value.as_ref().map(|value| {
value
.as_str()
.map_or_else(|| value.to_string(), str::to_owned)
})
})
.or_else(|| {
(field.key == STYLE_LEVEL_KEY).then(|| crate::style::StyleLevel::Full.to_string())
});
match &field.kind {
FieldKind::Bool => Some((base.as_deref() != Some("true")).to_string()),
FieldKind::Choice(names) => {
let at = base
.and_then(|base| names.iter().position(|name| *name == base))
.map_or(0, |index| index + 1);
names.get(at % names.len().max(1)).cloned()
}
_ => None,
}
}
fn armed_for(&self, field: &Field) -> bool {
matches!(
&self.pending,
Some(Pending::Armed { edit, .. }) if edit.key() == field.key
)
}
}