Skip to content

Commit 7e3f67d

Browse files
committed
refactor
1 parent e924a59 commit 7e3f67d

File tree

8 files changed

+97
-95
lines changed

8 files changed

+97
-95
lines changed

git-protocol/src/packet_line.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// pub fn decode(data: &[u8]) -> Result<>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use quick_error::quick_error;
2+
use std::io;
3+
4+
const MAX_DATA_LEN: usize = 65516;
5+
6+
quick_error! {
7+
#[derive(Debug)]
8+
pub enum Error {
9+
Io(err: io::Error) {
10+
display("An error occurred while writing")
11+
from()
12+
source(err)
13+
}
14+
DataLengthLimitExceeded(length_in_bytes: usize) {
15+
display("Cannot encode more than {} bytes, got {}", MAX_DATA_LEN, length_in_bytes)
16+
}
17+
DataIsEmpty {
18+
display("Empty lines are invalid")
19+
}
20+
}
21+
}
22+
pub fn flush_to_write(mut out: impl io::Write) -> io::Result<usize> {
23+
out.write_all(b"0000").map(|_| 4)
24+
}
25+
26+
pub fn data_to_write(data: &[u8], mut out: impl io::Write) -> Result<usize, Error> {
27+
if data.len() > MAX_DATA_LEN {
28+
return Err(Error::DataLengthLimitExceeded(data.len()));
29+
}
30+
if data.is_empty() {
31+
return Err(Error::DataIsEmpty);
32+
}
33+
34+
let mut buf = [0u8; 4];
35+
let data_len = data.len() + 4;
36+
hex::encode_to_slice((data_len as u16).to_be_bytes(), &mut buf).expect("two bytes to 4 hex chars never fails");
37+
out.write_all(&buf)?;
38+
out.write_all(data)?;
39+
Ok(data_len)
40+
}

git-protocol/src/packet_line/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod decode;
2+
pub mod encode;

git-protocol/tests/packet_line/decode.rs

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
mod data_to_write {
2+
use bstr::ByteSlice;
3+
use git_protocol::packet_line::encode::{data_to_write, flush_to_write};
4+
use std::io;
5+
6+
fn vec_sized(size: usize) -> Vec<u8> {
7+
let mut v = Vec::new();
8+
v.resize(size, 0);
9+
v
10+
}
11+
12+
fn assert_err_display<T, E: std::error::Error>(res: Result<T, E>, expected: impl AsRef<str>) {
13+
match res {
14+
Ok(_) => assert!(false, "Expected error '{}', got value", expected.as_ref()),
15+
Err(err) => assert_eq!(err.to_string(), expected.as_ref()),
16+
}
17+
}
18+
19+
#[test]
20+
fn success_binary_and_non_binary() -> crate::Result {
21+
let mut out = Vec::new();
22+
assert_eq!(data_to_write(b"\0", &mut out)?, 5);
23+
assert_eq!(out.as_bstr(), b"0005\0".as_bstr());
24+
25+
out.clear();
26+
assert_eq!(data_to_write("hello world, it works\n".as_bytes(), &mut out)?, 26);
27+
assert_eq!(out.as_bstr(), b"001ahello world, it works\n".as_bstr());
28+
Ok(())
29+
}
30+
31+
#[test]
32+
fn success_flush() -> crate::Result {
33+
let mut out = Vec::new();
34+
assert_eq!(flush_to_write(&mut out)?, 4);
35+
assert_eq!(out.as_bstr(), b"0000".as_bstr());
36+
Ok(())
37+
}
38+
39+
#[test]
40+
fn error_if_data_exceeds_limit() {
41+
assert_err_display(
42+
data_to_write(&vec_sized(65516 + 1), io::sink()),
43+
"Cannot encode more than 65516 bytes, got 65517",
44+
);
45+
}
46+
#[test]
47+
fn error_if_data_is_empty() {
48+
assert_err_display(data_to_write(&[], io::sink()), "Empty lines are invalid");
49+
}
50+
}

git-protocol/tests/packet_line/mod.rs

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,2 @@
1-
mod encode {
2-
mod data_to_write {
3-
use bstr::ByteSlice;
4-
use git_protocol::packet_line::encode::{data_to_write, flush_to_write};
5-
use std::io;
6-
7-
fn vec_sized(size: usize) -> Vec<u8> {
8-
let mut v = Vec::new();
9-
v.resize(size, 0);
10-
v
11-
}
12-
13-
fn assert_err_display<T, E: std::error::Error>(res: Result<T, E>, expected: impl AsRef<str>) {
14-
match res {
15-
Ok(_) => assert!(false, "Expected error '{}', got value", expected.as_ref()),
16-
Err(err) => assert_eq!(err.to_string(), expected.as_ref()),
17-
}
18-
}
19-
20-
#[test]
21-
fn success_binary_and_non_binary() -> crate::Result {
22-
let mut out = Vec::new();
23-
assert_eq!(data_to_write(b"\0", &mut out)?, 5);
24-
assert_eq!(out.as_bstr(), b"0005\0".as_bstr());
25-
26-
out.clear();
27-
assert_eq!(data_to_write("hello world, it works\n".as_bytes(), &mut out)?, 26);
28-
assert_eq!(out.as_bstr(), b"001ahello world, it works\n".as_bstr());
29-
Ok(())
30-
}
31-
32-
#[test]
33-
fn success_flush() -> crate::Result {
34-
let mut out = Vec::new();
35-
assert_eq!(flush_to_write(&mut out)?, 4);
36-
assert_eq!(out.as_bstr(), b"0000".as_bstr());
37-
Ok(())
38-
}
39-
40-
#[test]
41-
fn error_if_data_exceeds_limit() {
42-
assert_err_display(
43-
data_to_write(&vec_sized(65516 + 1), io::sink()),
44-
"Cannot encode more than 65516 bytes, got 65517",
45-
);
46-
}
47-
#[test]
48-
fn error_if_data_is_empty() {
49-
assert_err_display(data_to_write(&[], io::sink()), "Empty lines are invalid");
50-
}
51-
}
52-
}
1+
mod decode;
2+
mod encode;

tasks.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
* `PATH="$PWD:$PATH" git -c core.gitproxy="git-proxy" clone git://localhost:9419/small-test`
66
* to be used to obtain more real-world samples of typical git interactions for use in the test-suite
77
* **git-protocol**
8-
* [ ] parse pkt-lines support
8+
* [ ] pkt-lines support
99
* [x] encoding including flush lines
10+
* [ ] decoding
1011
* [ ] basic V1 parsing to understand data frames to allow placing them into individual files
1112
* **a way to intercept git-http communication**
1213
* Maybe with a custom proxy as well, can't hurt to try APIs in real-world programs

0 commit comments

Comments
 (0)