@@ -6,6 +6,10 @@ pub enum Error {
6
6
NegativeWithDestination ,
7
7
#[ error( "Cannot push into an empty destination" ) ]
8
8
PushToEmpty ,
9
+ #[ error( "glob patterns may only involved a single '*' character, found {pattern:?}" ) ]
10
+ PatternUnsupported { pattern : bstr:: BString } ,
11
+ #[ error( "Both sides of the specification need a pattern, like 'a/*:b/*'" ) ]
12
+ PatternUnbalanced ,
9
13
}
10
14
11
15
pub ( crate ) mod function {
@@ -48,17 +52,35 @@ pub(crate) mod function {
48
52
Operation :: Push => return Err ( Error :: PushToEmpty ) ,
49
53
Operation :: Fetch => ( Some ( src) , None ) ,
50
54
} ,
51
- _ => todo ! ( " src or dst handling" ) ,
55
+ ( Some ( src ) , Some ( dst ) ) => ( Some ( src) , Some ( dst) ) ,
52
56
}
53
57
}
54
- None => todo ! ( "no colon" ) ,
58
+ None => ( Some ( spec ) , None ) ,
55
59
} ;
56
60
61
+ let ( src, src_had_pattern) = validated ( src) ?;
62
+ let ( dst, dst_had_pattern) = validated ( dst) ?;
63
+ if src_had_pattern != dst_had_pattern {
64
+ return Err ( Error :: PatternUnbalanced ) ;
65
+ }
57
66
Ok ( RefSpecRef {
58
67
op : operation,
59
68
mode,
60
69
src,
61
70
dst,
62
71
} )
63
72
}
73
+
74
+ fn validated ( spec : Option < & BStr > ) -> Result < ( Option < & BStr > , bool ) , Error > {
75
+ match spec {
76
+ Some ( spec) => {
77
+ let glob_count = spec. iter ( ) . filter ( |b| * * b == b'*' ) . take ( 2 ) . count ( ) ;
78
+ if glob_count == 2 {
79
+ return Err ( Error :: PatternUnsupported { pattern : spec. into ( ) } ) ;
80
+ }
81
+ Ok ( ( Some ( spec) , glob_count == 1 ) )
82
+ }
83
+ None => Ok ( ( None , false ) ) ,
84
+ }
85
+ }
64
86
}
0 commit comments