use super::ram::{BirthMemo, FrozenMemo};
use super::{BRANCH, PROVIDERS, PickerState};
use crate::config_edit::branch::config_file;
use crate::model_pick::{ConfigPoint, ConfigTip, ModelRow, birth_row, conversation_row, row_role};
use std::path::Path;
pub(super) fn conversation_row_of(
ws: &Path,
tip_oid: &str,
config_tip: Option<&ConfigTip>,
picker: &mut PickerState,
) -> Option<(String, ModelRow)> {
let key = (
tip_oid.to_owned(),
config_tip.map(|c| c.oid.clone()).unwrap_or_default(),
row_role(picker.role.as_deref()),
);
if picker.frozen.as_ref().is_none_or(|m| m.key != key) {
picker.frozen = memoize(ws, tip_oid, config_tip, key);
}
picker
.frozen
.as_ref()
.map(|m| (m.short_oid.clone(), m.row.clone()))
}
fn memoize(
ws: &Path,
tip_oid: &str,
config_tip: Option<&ConfigTip>,
key: (String, String, String),
) -> Option<FrozenMemo> {
let gov = crate::config_edit::branch::governing_config(ws, tip_oid).ok()?;
let governing = point(ws, gov.oid, gov.short_oid.clone());
let tip = config_tip.map_or_else(
|| governing.clone(),
|c| point(ws, c.oid.clone(), c.short_oid.clone()),
);
let row = conversation_row(&governing, &tip, &key.2);
Some(FrozenMemo {
key,
row,
short_oid: gov.short_oid,
})
}
pub(super) fn birth_row_of(
ws: &Path,
config_tip: Option<&ConfigTip>,
picker: &mut PickerState,
) -> Option<ModelRow> {
let tip = config_tip?;
let key = (tip.oid.clone(), row_role(picker.role.as_deref()));
if picker.birth.as_ref().is_none_or(|memo| memo.key != key) {
let at = point(ws, tip.oid.clone(), tip.short_oid.clone());
let row = birth_row(&at, &key.1, BRANCH);
picker.birth = Some(BirthMemo { key, row });
}
picker.birth.as_ref().map(|memo| memo.row.clone())
}
fn point(ws: &Path, oid: String, short_oid: String) -> ConfigPoint {
let raw = config_file(ws, &oid, PROVIDERS).unwrap_or_default();
ConfigPoint {
oid,
short_oid,
providers_yaml: String::from_utf8_lossy(&raw).into_owned(),
}
}