1use std::fmt::Display;
2use std::ops::Deref;
3use std::path::Path;
4
5use owo_colors::OwoColorize as _;
6use rootcause::prelude::ResultExt as _;
7use ytil_git::branch::Branch;
8
9struct RenderableBranch(pub Branch);
11
12impl Deref for RenderableBranch {
13 type Target = Branch;
14
15 fn deref(&self) -> &Self::Target {
16 &self.0
17 }
18}
19
20impl Display for RenderableBranch {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 let styled_date_time = format!("({})", self.committer_date_time());
23 let styled_email = format!("<{}>", self.committer_email());
24 write!(
25 f,
26 "{} {} {}",
27 self.name(),
28 styled_date_time.green(),
29 styled_email.blue().bold(),
30 )
31 }
32}
33
34pub fn select() -> rootcause::Result<Option<Branch>> {
43 let repo = ytil_git::repo::discover(Path::new(".")).context("error discovering repo for branch selection")?;
44 let mut branches = ytil_git::branch::get_all_no_redundant(&repo)?;
45
46 if let Some(prev) = ytil_git::branch::get_previous(&repo)
47 && let Some(idx) = branches.iter().position(|b| b.name_no_origin() == prev)
48 {
49 let branch = branches.remove(idx);
50 branches.insert(0, branch);
51 }
52
53 let Some(branch) = crate::minimal_select(branches.into_iter().map(RenderableBranch).collect())? else {
54 return Ok(None);
55 };
56
57 Ok(Some(branch.0))
58}