use crate::error::{FossilError, Result};
use crate::repo::{CheckIn, Repository};
enum BranchSource {
Branch(String),
Tag(String),
Commit(String),
}
pub struct BranchesBuilder<'a> {
repo: &'a Repository,
}
impl<'a> BranchesBuilder<'a> {
pub(crate) fn new(repo: &'a Repository) -> Self {
Self { repo }
}
pub fn list(&self) -> Result<Vec<String>> {
self.repo.list_branches_internal()
}
pub fn get(&self, name: &str) -> Result<BranchRef<'a>> {
self.repo.branch_tip_internal(name)?;
Ok(BranchRef {
repo: self.repo,
name: name.to_string(),
})
}
pub fn create(&self, name: &str) -> BranchBuilder<'a> {
BranchBuilder {
repo: self.repo,
name: name.to_string(),
source: None,
author: None,
}
}
}
pub struct BranchRef<'a> {
repo: &'a Repository,
name: String,
}
impl<'a> BranchRef<'a> {
pub fn tip(&self) -> Result<CheckIn> {
self.repo.branch_tip_internal(&self.name)
}
pub fn name(&self) -> &str {
&self.name
}
}
pub struct BranchBuilder<'a> {
repo: &'a Repository,
name: String,
source: Option<BranchSource>,
author: Option<String>,
}
impl<'a> BranchBuilder<'a> {
pub fn from_branch(mut self, branch: &str) -> Self {
self.source = Some(BranchSource::Branch(branch.to_string()));
self
}
pub fn from_tag(mut self, tag: &str) -> Self {
self.source = Some(BranchSource::Tag(tag.to_string()));
self
}
pub fn from_commit(mut self, hash: &str) -> Self {
self.source = Some(BranchSource::Commit(hash.to_string()));
self
}
pub fn author(mut self, user: &str) -> Self {
self.author = Some(user.to_string());
self
}
pub fn execute(self) -> Result<String> {
let author = self
.author
.ok_or_else(|| FossilError::InvalidArtifact("branch author is required".to_string()))?;
let source = self.source.ok_or_else(|| {
FossilError::InvalidArtifact(
"branch source is required (use from_branch, from_tag, or from_commit)".to_string(),
)
})?;
let parent_hash = match source {
BranchSource::Branch(name) => {
let tip = self.repo.branch_tip_internal(&name)?;
tip.hash
}
BranchSource::Tag(name) => self.repo.get_tag_checkin_internal(&name)?,
BranchSource::Commit(hash) => hash,
};
self.repo
.create_branch_internal(&self.name, &parent_hash, &author)
}
}