I'm convinced there is a way to handle this 'cleanly', I am just not quite figuring it out.
use git2::Repository;
// Prints out the current branch and sha if it exists.
fn report_repo() -> () {
Repository::open(".")
.ok()
.and_then(branch_and_sha)
.and_then(|branch_sha| => { // Fails here with E0061
let (branch, sha) = branch_sha;
println!("Branch={} sha={}", branch, sha);
None
});
}
fn branch_and_sha(repo: Repository) -> Option<(String, String)> {
match repo.head().ok() {
Some(reference) => {
match (reference.name(), reference.target()){
(Some(branch), Some(sha)) => Some((branch.to_string(), sha.to_string())),
_ => None
}
},
None => None
}
}
The error that arises is E0061, and I think it's because the 'value' in the Option returned from branch_and_sha()
is a tuple. branch_and_sha()
effectively says, "If there is a repository, get it's reference, and if that exists, if it has both a name (branch) and target (sha), return an Option<(String, String)>
with that info - otherwise return None
. And the reporting function wants to do something if all of the Repository
, branch and sha can be found - and nothing otherwise. (It shouldn't error or panic.)
To some degree this is contrived - it's an example of an optimistic reporting function similar to several I'd like to write. I'm looking for a clean, idiomatic way to do it. The key thrust is 'several depths and several branches could return None
which should cause a no-op, and otherwise make specific (leaf) info available.' The specific error is how I should be handling the and_then
function, which is surprisingly difficult to find similar problems about.