1mod branch;
2mod rebase;
3mod render;
4
5pub use branch::{BranchInfo, Node, Topology};
6pub use render::render;
7
8use grit::trunk;
9
10pub async fn topology() -> Result<Topology, Error> {
16 let trunk = trunk::local().await.map_err(Error::Trunk)?;
17 branch::collect(&trunk).await.map_err(Error::Git)
18}
19
20pub async fn rebase(branch_name: &str) -> Result<(), Error> {
26 let trunk = trunk::local().await.map_err(Error::Trunk)?;
27 let topology = branch::collect(&trunk).await.map_err(Error::Git)?;
28
29 let Some(node) = find_branch_node(&topology.root, branch_name) else {
31 return Err(Error::BranchNotFound(branch_name.to_owned()));
32 };
33
34 rebase::rebase_stack(&trunk, node).await.map_err(Error::Git)
35}
36
37fn find_branch_node<'a>(node: &'a Node, name: &str) -> Option<&'a Node> {
39 if node.branches.iter().any(|info| info.name == name) {
41 return Some(node);
42 }
43
44 for child in &node.children {
46 if let Some(found) = find_branch_node(child, name) {
47 return Some(found);
48 }
49 }
50
51 None
52}
53
54#[derive(Debug)]
55pub enum Error {
56 Trunk(trunk::Error),
57 Git(grit::git::Error),
58 BranchNotFound(String),
59}
60
61impl std::fmt::Display for Error {
62 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 match self {
64 Error::Trunk(e) => write!(f, "{e}"),
65 Error::Git(e) => write!(f, "{e}"),
66 Error::BranchNotFound(name) => write!(f, "branch not found: {name}"),
67 }
68 }
69}