Skip to content

Commit e214df5

Browse files
committed
[clone] as_read() support for packet lines
1 parent 7178543 commit e214df5

File tree

3 files changed

+30
-32
lines changed

3 files changed

+30
-32
lines changed

git-packetline/src/read.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::io;
1111
/// Read pack lines one after another, without consuming more than needed from the underlying
1212
/// `Read`. `Flush` lines cause the reader to stop producing lines forever, leaving `Read` at the
1313
/// start of whatever comes next.
14-
/// It signals encountering a flush line with `UnexpectedEof`
1514
pub struct Reader<T> {
1615
pub inner: T,
1716
buf: Vec<u8>,
@@ -54,22 +53,16 @@ where
5453
}
5554
}
5655

57-
pub fn read_line(&mut self) -> io::Result<Result<PacketLine, decode::Error>> {
58-
let eof = || {
59-
Err(io::Error::new(
60-
io::ErrorKind::UnexpectedEof,
61-
"attempt to read past flush line",
62-
))
63-
};
56+
pub fn read_line(&mut self) -> Option<io::Result<Result<PacketLine, decode::Error>>> {
6457
if self.is_done {
65-
return eof();
58+
return None;
6659
}
6760
match Self::read_line_inner(&mut self.inner, &mut self.buf) {
6861
Ok(Ok(line)) if line == self.delimiter => {
6962
self.is_done = true;
70-
eof()
63+
None
7164
}
72-
err => err,
65+
res => Some(res),
7366
}
7467
}
7568

@@ -139,10 +132,10 @@ where
139132
if self.pos >= self.cap {
140133
debug_assert!(self.pos == self.cap);
141134
self.cap = loop {
142-
let line = self
143-
.parent
144-
.read_line()?
145-
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
135+
let line = match self.parent.read_line() {
136+
Some(line) => line?.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?,
137+
None => break 0,
138+
};
146139
match self.progress_and_parse.as_mut() {
147140
Some((progress, parse_progress)) => {
148141
let mut band = line

git-packetline/tests/packet_line/read.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use git_packetline::PacketLine;
2-
use std::{io, path::PathBuf};
2+
use std::io;
3+
use std::path::PathBuf;
34

45
fn fixture_path(path: &str) -> PathBuf {
56
PathBuf::from("tests/fixtures").join(path)
@@ -10,7 +11,7 @@ fn fixture_bytes(path: &str) -> Vec<u8> {
1011
}
1112

1213
mod to_read {
13-
use crate::packet_line::read::{exhaust, fixture_bytes};
14+
use crate::packet_line::read::fixture_bytes;
1415
use bstr::ByteSlice;
1516
use git_odb::pack;
1617
use git_packetline::RemoteProgress;
@@ -21,13 +22,13 @@ mod to_read {
2122
let buf = fixture_bytes("v1/01-clone.combined-output");
2223
let mut rd = git_packetline::Reader::new(&buf[..], None);
2324

25+
// Read without sideband decoding
2426
let mut out = Vec::new();
2527
rd.as_read().read_to_end(&mut out)?;
26-
assert_eq!(out.as_bstr(), b"foo".as_bstr());
28+
assert_eq!(out.as_bstr(), b"808e50d724f604f69ab93c6da2919c014667bedb HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed symref=HEAD:refs/heads/master object-format=sha1 agent=git/2.28.0\n808e50d724f604f69ab93c6da2919c014667bedb refs/heads/master\n".as_bstr());
2729

28-
assert_eq!(exhaust(&mut rd), 2);
2930
rd.reset();
30-
assert_eq!(rd.read_line()??.to_text().0.as_bstr(), b"NAK".as_bstr());
31+
assert_eq!(rd.read_line().expect("line")??.to_text().0.as_bstr(), b"NAK".as_bstr());
3132
fn no_parsing(_: &[u8]) -> Option<RemoteProgress> {
3233
None
3334
}
@@ -55,7 +56,7 @@ fn read_from_file_and_reader_advancement() -> crate::Result {
5556
bytes.extend(fixture_bytes("v1/fetch/01-many-refs.response").into_iter());
5657
let mut rd = git_packetline::Reader::new(&bytes[..], None);
5758
assert_eq!(
58-
rd.read_line()??.as_bstr(),
59+
rd.read_line().expect("line")??.as_bstr(),
5960
PacketLine::Data(b"7814e8a05a59c0cf5fb186661d1551c75d1299b5 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed symref=HEAD:refs/heads/master object-format=sha1 agent=git/2.28.0\n").as_bstr()
6061
);
6162
assert_eq!(exhaust(&mut rd) + 1, 1561, "it stops after seeing the flush byte");
@@ -65,18 +66,20 @@ fn read_from_file_and_reader_advancement() -> crate::Result {
6566
1561,
6667
"it should read the second part of the identical file from the previously advanced reader"
6768
);
69+
70+
// this reset is will cause actual io::Errors to occour
6871
rd.reset();
6972
assert_eq!(
70-
rd.read_line().unwrap_err().kind(),
73+
rd.read_line().expect("some error").unwrap_err().kind(),
7174
io::ErrorKind::UnexpectedEof,
72-
"trying to keep reading from exhausted input propagates the error"
75+
"trying to keep reading from exhausted input results in Some() containing the original error"
7376
);
7477
Ok(())
7578
}
7679

7780
fn exhaust(rd: &mut git_packetline::Reader<&[u8]>) -> i32 {
7881
let mut count = 0;
79-
while let Ok(_) = rd.read_line() {
82+
while let Some(_) = rd.read_line() {
8083
count += 1;
8184
}
8285
count

tasks.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
### Cloning
22
* **gixp-pack-receive**
33
* _a program to (initially only) clone from a given URL_, storing a full pack with index only. No support for `git-refs`.
4-
* [x] pkt-lines support
5-
* [x] Don't forcibly remove newlines at the end of pack lines, but make that an extra step.
6-
* [x] decode band should be able to fail
7-
* [x] PacketLine 'Iterator' from `Read`
8-
* [x] `Read` from packet lines with sideband
9-
* [x] Progress parsing, with 'info(…)' fallback if that fails
10-
* [x] SetName in Progress trait (to allow setting the correct progress information)
11-
* [ ] Disable sideband support (e.g. github http V2 doesn't have it)
4+
* **git-packetline**
5+
* [x] pkt-lines support
6+
* [x] Don't forcibly remove newlines at the end of pack lines, but make that an extra step.
7+
* [x] decode band should be able to fail
8+
* [x] PacketLine 'Iterator' from `Read`
9+
* [x] `Read` from packet lines with sideband
10+
* [x] Progress parsing, with 'info(…)' fallback if that fails
11+
* [x] SetName in Progress trait (to allow setting the correct progress information)
12+
* [x] Disable sideband support (e.g. github http V2 doesn't have it)
13+
* [ ] don't coerce line delimiters into empty slices.
1214
* **git-url**
1315
* [ ] parse into components to make them easy to understand
1416
* **connect**

0 commit comments

Comments
 (0)