File tree 6 files changed +46
-9
lines changed
6 files changed +46
-9
lines changed Original file line number Diff line number Diff line change @@ -94,11 +94,11 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
94
94
some sort of reactor which feeds the client/server respectively with deserialized lines. This enables us to
95
95
start out with a sync implementation, and later add an async one that reuses all the protocol code.
96
96
* [ ] [ PKT-Line] ( https://github.com/git/git/blob/master/Documentation/technical/protocol-common.txt#L52:L52 )
97
- * [ ] encode
98
- * [ ] decode (zero-copy)
99
- * [ ] [ error line] ( https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L28:L28 )
97
+ * [x ] encode
98
+ * [x ] decode (zero-copy)
99
+ * [x ] [ error line] ( https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L28:L28 )
100
100
* [ ] [ V2 additions] ( https://github.com/git/git/blob/master/Documentation/technical/protocol-v2.txt#L35:L36 )
101
- * [ ]
101
+ * [ ] [ side-band mode ] ( https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L467:L467 )
102
102
* [ ] ` Iterator ` for multi-plexed pack lines from ` Read `
103
103
* [ ] parse and serialize [ capabilities] ( https://github.com/git/git/blob/master/Documentation/technical/protocol-capabilities.txt#L1:L1 )
104
104
* [ ] ** Version 1**
@@ -111,7 +111,6 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
111
111
* [ ] multi-ack
112
112
* [ ] multi-ack detailed
113
113
* [ ] [ server-response (pack)] ( https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L404:L404 )
114
- * [ ] [ side-band mode] ( https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L467:L467 )
115
114
* [ ] push
116
115
* [ ] [ Version 2] ( https://github.com/git/git/blob/master/Documentation/technical/protocol-v2.txt )
117
116
Original file line number Diff line number Diff line change 1
- use crate :: packet_line:: { FLUSH_LINE , MAX_DATA_LEN } ;
1
+ use crate :: packet_line:: { ERR_PREFIX , FLUSH_LINE , MAX_DATA_LEN } ;
2
2
use quick_error:: quick_error;
3
3
use std:: io;
4
4
@@ -18,10 +18,23 @@ quick_error! {
18
18
}
19
19
}
20
20
}
21
+
21
22
pub fn flush_to_write ( mut out : impl io:: Write ) -> io:: Result < usize > {
22
23
out. write_all ( FLUSH_LINE ) . map ( |_| 4 )
23
24
}
24
25
26
+ pub fn error_to_write ( data : & [ u8 ] , out : impl io:: Write ) -> Result < usize , Error > {
27
+ let data_with_prefix_end = data. len ( ) + ERR_PREFIX . len ( ) ;
28
+ if data_with_prefix_end > MAX_DATA_LEN {
29
+ return Err ( Error :: DataLengthLimitExceeded ( data. len ( ) - ERR_PREFIX . len ( ) ) ) ;
30
+ }
31
+ // This is a big buffer, but it's only used on error, so the program is on the way out
32
+ let mut buf = [ 0u8 ; MAX_DATA_LEN ] ;
33
+ buf[ ..ERR_PREFIX . len ( ) ] . copy_from_slice ( ERR_PREFIX ) ;
34
+ buf[ ERR_PREFIX . len ( ) ..data_with_prefix_end] . copy_from_slice ( data) ;
35
+ data_to_write ( & buf[ ..data_with_prefix_end] , out)
36
+ }
37
+
25
38
pub fn data_to_write ( data : & [ u8 ] , mut out : impl io:: Write ) -> Result < usize , Error > {
26
39
if data. len ( ) > MAX_DATA_LEN {
27
40
return Err ( Error :: DataLengthLimitExceeded ( data. len ( ) ) ) ;
Original file line number Diff line number Diff line change @@ -31,6 +31,17 @@ impl<'a> Borrowed<'a> {
31
31
pub fn as_bstr ( & self ) -> & BStr {
32
32
self . as_slice ( ) . into ( )
33
33
}
34
+ pub fn to_error ( & self ) -> Error {
35
+ Error ( self . as_slice ( ) )
36
+ }
37
+ }
38
+
39
+ pub struct Error < ' a > ( & ' a [ u8 ] ) ;
40
+
41
+ impl < ' a > Error < ' a > {
42
+ pub fn to_write ( & self , out : impl io:: Write ) -> Result < usize , encode:: Error > {
43
+ encode:: error_to_write ( self . 0 , out)
44
+ }
34
45
}
35
46
36
47
pub mod decode;
Original file line number Diff line number Diff line change @@ -74,6 +74,14 @@ mod streaming {
74
74
Ok ( ( ) )
75
75
}
76
76
77
+ #[ test]
78
+ fn roundtrip_error_line ( ) -> crate :: Result {
79
+ let mut out = Vec :: new ( ) ;
80
+ PacketLine :: Data ( b"the error" ) . to_error ( ) . to_write ( & mut out) ?;
81
+ assert_err_display ( streaming ( & out) , "the error" ) ;
82
+ Ok ( ( ) )
83
+ }
84
+
77
85
mod incomplete {
78
86
use git_protocol:: packet_line:: decode:: { self , streaming, Stream } ;
79
87
Original file line number Diff line number Diff line change 1
1
mod data_to_write {
2
2
use crate :: packet_line:: assert_err_display;
3
3
use bstr:: ByteSlice ;
4
- use git_protocol:: packet_line:: encode:: { data_to_write, flush_to_write} ;
4
+ use git_protocol:: packet_line:: encode:: { data_to_write, error_to_write , flush_to_write} ;
5
5
use std:: io;
6
6
7
7
fn vec_sized ( size : usize ) -> Vec < u8 > {
@@ -30,6 +30,14 @@ mod data_to_write {
30
30
Ok ( ( ) )
31
31
}
32
32
33
+ #[ test]
34
+ fn successful_write_of_error_line ( ) -> crate :: Result {
35
+ let mut out = Vec :: new ( ) ;
36
+ assert_eq ! ( error_to_write( b"hello error" , & mut out) ?, 19 ) ;
37
+ assert_eq ! ( out. as_bstr( ) , b"0013ERR hello error" . as_bstr( ) ) ;
38
+ Ok ( ( ) )
39
+ }
40
+
33
41
#[ test]
34
42
fn error_if_data_exceeds_limit ( ) {
35
43
assert_err_display (
Original file line number Diff line number Diff line change 6
6
* to be used to obtain more real-world samples of typical git interactions for use in the test-suite
7
7
* ** git-protocol**
8
8
* [ ] pkt-lines support
9
- * [x] encoding including flush lines
10
- * [ ] decoding
11
9
* [ ] basic V1 parsing to understand data frames to allow placing them into individual files
12
10
* ** a way to intercept git-http communication**
13
11
* Maybe with a custom proxy as well, can't hurt to try APIs in real-world programs
You can’t perform that action at this time.
0 commit comments