@@ -50,6 +50,7 @@ pub mod parse {
50
50
}
51
51
52
52
pub ( crate ) mod function {
53
+ use crate :: spec;
53
54
use crate :: spec:: parse:: { Delegate , Error } ;
54
55
use bstr:: { BStr , ByteSlice } ;
55
56
@@ -58,17 +59,40 @@ pub mod parse {
58
59
( b, i[ 1 ..] . as_bstr ( ) ) . into ( )
59
60
}
60
61
62
+ pub fn revision < ' a > ( mut input : & ' a BStr , delegate : & mut impl Delegate ) -> Result < & ' a BStr , Error > {
63
+ if let Some ( rest) = input. strip_prefix ( b"@" ) . or_else ( || input. strip_prefix ( b"HEAD" ) ) {
64
+ delegate. resolve_ref ( "HEAD" . into ( ) ) . ok_or ( Error :: Delegate ) ?;
65
+ input = rest. as_bstr ( ) ;
66
+ }
67
+ Ok ( input)
68
+ }
69
+
61
70
pub fn parse ( mut input : & BStr , delegate : & mut impl Delegate ) -> Result < ( ) , Error > {
62
71
if let Some ( b'^' ) = input. get ( 0 ) {
63
72
input = next ( input) . 1 ;
64
- delegate. kind ( crate :: spec:: Kind :: Range ) ;
73
+ delegate. kind ( spec:: Kind :: Range ) ;
65
74
}
66
75
67
- if input == "@" || input == "HEAD" {
68
- return delegate. resolve_ref ( "HEAD" . into ( ) ) . ok_or ( Error :: Delegate ) ;
76
+ input = revision ( input, delegate) ?;
77
+ if let Some ( ( rest, kind) ) = try_range ( input) {
78
+ // TODO: protect against double-kind calls, invalid for git
79
+ delegate. kind ( kind) ;
80
+ input = rest. as_bstr ( ) ;
69
81
}
70
82
71
- todo ! ( "" )
83
+ assert ! (
84
+ input. is_empty( ) ,
85
+ "BUG: we must parse all of our input or fail gracefully: {:?}" ,
86
+ input
87
+ ) ;
88
+ Ok ( ( ) )
89
+ }
90
+
91
+ fn try_range ( input : & BStr ) -> Option < ( & [ u8 ] , spec:: Kind ) > {
92
+ input
93
+ . strip_prefix ( b"..." )
94
+ . map ( |rest| ( rest, spec:: Kind :: MergeBase ) )
95
+ . or_else ( || input. strip_prefix ( b".." ) . map ( |rest| ( rest, spec:: Kind :: Range ) ) )
72
96
}
73
97
}
74
98
}
0 commit comments