use super::*;
fn env_fold_key(name: &str) -> String {
format!("dogs.{name}.env")
}
impl Settings {
#[must_use]
pub fn snapshot(&self) -> &SettingsSnapshot {
&self.snapshot
}
#[must_use]
pub fn rows(&self) -> Vec<SettingsRow> {
let shape = shep_toml_shape();
let mut rows = Vec::new();
self.push_children(&shape.outline.roots, &mut rows);
for index in 0..self.snapshot.dogs.len() {
self.push_dog_rows(index, &mut rows);
}
rows
}
fn push_dog_rows(&self, index: usize, rows: &mut Vec<SettingsRow>) {
rows.push(SettingsRow::Dog(index));
let Some(dog) = self.snapshot.dogs.get(index) else {
return;
};
let Some(tree) = self.dog_trees.get(&dog.name) else {
return;
};
if !tree.is_open() {
return;
}
for key in DogKey::ALL {
rows.push(SettingsRow::DogKey { dog: index, key });
if key != DogKey::Grants {
continue;
}
rows.extend((0..dog.offered.len()).map(|item| SettingsRow::DogGrant {
dog: index,
index: item,
}));
}
if dog.adopted_path.is_some() {
rows.push(SettingsRow::DogEnv(index));
if !self.folded.contains(&env_fold_key(&dog.name)) {
rows.extend((0..dog.env_keys.len()).map(|key| SettingsRow::DogEnvKey {
dog: index,
index: key,
}));
rows.push(SettingsRow::DogEnvNew(index));
}
}
let Some(pane) = tree.pane() else {
return;
};
rows.extend(
pane.rows()
.iter()
.enumerate()
.filter(|(_, row)| pane.tree_row((*row).to_owned()).is_some())
.map(|(row, _)| SettingsRow::DogField { dog: index, row }),
);
}
fn push_children(&self, children: &[Child], rows: &mut Vec<SettingsRow>) {
let shape = shep_toml_shape();
for child in children {
match *child {
Child::Table(index) => {
rows.push(SettingsRow::Table(index));
let table = &shape.outline.tables[index];
if !self.folded.contains(&table.path) {
self.push_children(&table.children, rows);
}
}
Child::Leaf(index) => {
rows.push(SettingsRow::Field(index));
let field = &shape.fields.fields()[index];
if field.kind == FieldKind::Map && !self.folded.contains(&field.key) {
let entries = self.snapshot.entries(&field.key).len();
rows.extend((0..entries).map(|entry| SettingsRow::Entry {
map: index,
index: entry,
}));
rows.push(SettingsRow::AddEntry(index));
}
}
}
}
}
#[must_use]
pub fn rows_len(&self) -> usize {
self.rows().len()
}
#[must_use]
pub fn cursor(&self) -> Option<SettingsRow> {
let rows = self.rows();
rows.get(self.view.cursor().min(rows.len().saturating_sub(1)))
.copied()
}
pub(in crate::lookout::app) fn toggle_fold(&mut self) -> bool {
let shape = shep_toml_shape();
let key = match self.cursor() {
Some(SettingsRow::Table(index)) => shape.outline.tables[index].path.clone(),
Some(SettingsRow::Field(index))
if shape.fields.fields()[index].kind == FieldKind::Map =>
{
shape.fields.fields()[index].key.clone()
}
Some(SettingsRow::DogEnv(dog)) => match self.snapshot.dogs.get(dog) {
Some(dog) => env_fold_key(&dog.name),
None => return false,
},
_ => return false,
};
if !self.folded.remove(&key) {
self.folded.insert(key);
}
true
}
#[must_use]
pub fn is_open(&self, key: &str) -> bool {
!self.folded.contains(key)
}
#[must_use]
pub fn is_env_open(&self, name: &str) -> bool {
self.is_open(&env_fold_key(name))
}
pub(in crate::lookout::app) fn move_by(&mut self, delta: isize) {
let len = self.rows_len();
self.view.move_by(delta, len);
}
pub(in crate::lookout::app) fn move_to_first(&mut self) {
let len = self.rows_len();
self.view.move_to(0, len);
}
pub(in crate::lookout::app) fn move_to_last(&mut self) {
let len = self.rows_len();
self.view.move_to(len.saturating_sub(1), len);
}
#[must_use]
pub fn view(&self) -> &Viewport {
&self.view
}
pub fn set_rows(&mut self, rows: usize) {
let len = self.rows_len();
self.view.set_rows(rows, len);
}
}