Skip to content

Commit

Permalink
A basis for 'pure' parsing of rev-specs (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed May 29, 2022
1 parent ec37cb8 commit f2466dc
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
3 changes: 3 additions & 0 deletions git-revision/src/lib.rs
Expand Up @@ -10,3 +10,6 @@ pub use hash_hasher;
///
pub mod describe;
pub use describe::function::describe;

///
pub mod spec;
34 changes: 34 additions & 0 deletions git-revision/src/spec.rs
@@ -0,0 +1,34 @@
pub mod parse {
#![allow(missing_docs)]
use git_object::bstr::BStr;

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("The delegate didn't indicate success - check delegate for more information")]
Delegate,
}

pub trait Delegate {
fn resolve_ref(&mut self, input: &BStr) -> Option<()>;
fn find_by_prefix(&mut self, input: &BStr) -> Option<()>;

fn nth_ancestor(&mut self, n: usize) -> Option<()>;
fn nth_parent(&mut self, n: usize) -> Option<()>;
}

pub(crate) mod function {
use crate::spec::parse::{Delegate, Error};
use git_object::bstr::BStr;

pub fn parse(input: &BStr, delegate: &mut impl Delegate) -> Result<(), Error> {
// TODO: don't hardcode these cases, see how git does it. This remains
// just an example.
if input == "@" || input == "HEAD" {
return delegate.resolve_ref("HEAD".into()).ok_or(Error::Delegate);
}

todo!("")
}
}
}
pub use parse::function::parse;
1 change: 1 addition & 0 deletions git-revision/tests/revision.rs
@@ -1,3 +1,4 @@
mod describe;
mod spec;

pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error + 'static>>;
49 changes: 49 additions & 0 deletions git-revision/tests/spec/mod.rs
@@ -0,0 +1,49 @@
mod parse {
use git_object::bstr::{BStr, BString};
use git_revision::spec;
#[derive(Default, Debug)]
struct Recorder {
resolve_ref_input: Option<BString>,
}
impl spec::parse::Delegate for Recorder {
fn resolve_ref(&mut self, input: &BStr) -> Option<()> {
assert!(
self.resolve_ref_input.is_none(),
"called resolve_ref twice with '{}'",
input
);
self.resolve_ref_input = input.to_owned().into();
Some(())
}

fn find_by_prefix(&mut self, _input: &BStr) -> Option<()> {
todo!()
}

fn nth_ancestor(&mut self, _n: usize) -> Option<()> {
todo!()
}

fn nth_parent(&mut self, _n: usize) -> Option<()> {
todo!()
}
}

fn b(s: &str) -> &BStr {
s.into()
}

#[test]
fn at_alone_is_shortcut_for_head() {
let mut rec = Recorder::default();
spec::parse(b("@"), &mut rec).unwrap();
assert_eq!(rec.resolve_ref_input.unwrap(), "HEAD");
}

#[test]
fn refname() {
let mut rec = Recorder::default();
spec::parse(b("HEAD"), &mut rec).unwrap();
assert_eq!(rec.resolve_ref_input.unwrap(), "HEAD");
}
}

0 comments on commit f2466dc

Please sign in to comment.