History

refactor

Sebastian Thiel committed 6 years ago

Commit f2ff90d1 parent c1bcc0a7 files · +66 −49Browse files

Unified · Split

7 files
  1. git-packetline/src/provider/mod.rs +4 −0
  2. git-packetline/src/provider/read.rs +10 −0
  3. git-transport/src/client/git/mod.rs +2 −4
  4. git-transport/src/client/http/mod.rs +4 −5
  5. git-transport/src/client/mod.rs +10 −26
  6. git-transport/tests/client/git.rs +14 −12
  7. git-transport/tests/client/http.rs +22 −2
git-packetline/src/provider/mod.rs+4−0
@@ -144,6 +144,10 @@ where · 143 unmodified lines
144144 ReadWithSidebands::with_progress_handler(self, handle_progress)
145145 }
146146
147+ pub fn as_read_without_sidebands<F: FnMut(bool, &[u8])>(&mut self) -> ReadWithSidebands<T, F> {
148+ ReadWithSidebands::without_progress_handler(self)
149+ }
150+
147151 pub fn as_read(&mut self) -> ReadWithSidebands<T, fn(bool, &[u8])> {
148152 ReadWithSidebands::new(self)
149153 }
git-packetline/src/provider/read.rs+10−0
@@ -54,6 +54,16 @@ where · 53 unmodified lines
5454 }
5555 }
5656
57+ pub fn without_progress_handler(parent: &'a mut Provider<T>) -> Self {
58+ ReadWithSidebands {
59+ parent,
60+ handle_progress: None,
61+ buf: vec![0; MAX_DATA_LEN],
62+ pos: 0,
63+ cap: 0,
64+ }
65+ }
66+
5767 pub fn set_progress_handler(&mut self, handle_progress: Option<F>) {
5868 self.handle_progress = handle_progress;
5969 }
git-transport/src/client/git/mod.rs+2−4
@@ -41,14 +41,12 @@ where · 40 unmodified lines
4141 &mut self,
4242 write_mode: client::WriteMode,
4343 on_drop: Vec<client::MessageKind>,
44− handle_progress: Option<client::HandleProgress>,
4544 ) -> Result<client::RequestWriter, client::Error> {
46− Ok(client::RequestWriter::new(
45+ Ok(client::RequestWriter::new_from_bufread(
4746 &mut self.writer,
48− &mut self.line_provider,
47+ Box::new(self.line_provider.as_read_without_sidebands()),
4948 write_mode,
5049 on_drop,
51− handle_progress,
5250 ))
5351 }
5452 }
git-transport/src/client/http/mod.rs+4−5
@@ -103,7 +103,6 @@ impl<H: Http> client::Transport for Transport<H> { · 102 unmodified lines
103103 &mut self,
104104 write_mode: client::WriteMode,
105105 on_drop: Vec<client::MessageKind>,
106− handle_progress: Option<client::HandleProgress>,
107106 ) -> Result<client::RequestWriter, client::Error> {
108107 let service = self.service.expect("handshake() must have been called first");
109108 let url = append_url(&self.url, service.as_str());
@@ -113,22 +112,22 @@ impl<H: Http> client::Transport for Transport<H> { · 3 unmodified lines
113112 "Expect:".into(),
114113 ];
115114 let PostResponse {
116− headers,
115+ headers: _,
117116 body,
118117 post_body,
119118 } = self.http.post(&url, headers)?;
119+ // TODO: combine header handling with body reader
120120 // <Transport<H>>::check_content_type(service, "result", headers)?;
121121 let line_provider = self
122122 .line_provider
123123 .as_mut()
124124 .expect("handshake to have been called first");
125125 line_provider.replace(body);
126− Ok(RequestWriter::new(
126+ Ok(RequestWriter::new_from_bufread(
127127 post_body,
128− line_provider,
128+ Box::new(line_provider.as_read_without_sidebands()),
129129 write_mode,
130130 on_drop,
131− handle_progress,
132131 ))
133132 }
134133 }
git-transport/src/client/mod.rs+10−26
@@ -75,7 +75,7 @@ pub enum MessageKind { · 74 unmodified lines
7575 /// A type implementing `Write`, which when done can be transformed into a `Read` for obtaining the response.
7676 pub struct RequestWriter<'a> {
7777 pub(crate) writer: Box<dyn io::Write + 'a>,
78− pub(crate) reader: Box<dyn io::BufRead + 'a>,
78+ pub(crate) reader: Box<dyn SetProgressHandlerBufRead + 'a>,
7979 }
8080
8181 impl<'a> io::Write for RequestWriter<'a> {
@@ -89,26 +89,9 @@ impl<'a> io::Write for RequestWriter<'a> { · 7 unmodified lines
8989 }
9090
9191 impl<'a> RequestWriter<'a> {
92− pub fn new<R: io::Read, W: io::Write + 'a>(
93− writer: W,
94− line_provider: &'a mut git_packetline::Provider<R>,
95− write_mode: WriteMode,
96− on_drop: Vec<MessageKind>,
97− handle_progress: Option<HandleProgress>,
98− ) -> Self {
99− Self::new_from_bufread(
100− writer,
101− match handle_progress {
102− Some(handler) => Box::new(line_provider.as_read_with_sidebands(handler)),
103− None => Box::new(line_provider.as_read()),
104− },
105− write_mode,
106− on_drop,
107− )
108− }
10992 pub fn new_from_bufread<W: io::Write + 'a>(
11093 writer: W,
111− reader: Box<dyn io::BufRead + 'a>,
94+ reader: Box<dyn SetProgressHandlerBufRead + 'a>,
11295 write_mode: WriteMode,
11396 on_drop: Vec<MessageKind>,
11497 ) -> Self {
@@ -139,9 +122,15 @@ impl<'a, T: io::Read> SetProgressHandlerBufRead for git_packetline::provider::Re · 24 unmodified lines
139122 }
140123 }
141124
125+impl<'a> SetProgressHandlerBufRead for ResponseReader<'a> {
126+ fn set_progress_handler(&mut self, handle_progress: Option<HandleProgress>) {
127+ self.reader.set_progress_handler(handle_progress)
128+ }
129+}
130+
142131 /// A type implementing `Read` to obtain the server response.
143132 pub struct ResponseReader<'a> {
144− reader: Box<dyn io::BufRead + 'a>,
133+ reader: Box<dyn SetProgressHandlerBufRead + 'a>,
145134 }
146135
147136 impl<'a> io::Read for ResponseReader<'a> {
@@ -213,10 +202,5 @@ pub trait Transport { · 65 unmodified lines
213202 /// `send_mode` determines how calls to the `write(…)` method are interpreted, and `on_drop` determines what
214203 /// to do when the writer is consumed or dropped.
215204 /// If `handle_progress` is not None, it's function passed a text line without trailing LF from which progress information can be parsed.
216− fn request(
217− &mut self,
218− write_mode: WriteMode,
219− on_drop: Vec<MessageKind>,
220− handle_progress: Option<HandleProgress>,
221− ) -> Result<RequestWriter, Error>;
205+ fn request(&mut self, write_mode: WriteMode, on_drop: Vec<MessageKind>) -> Result<RequestWriter, Error>;
222206 }
git-transport/tests/client/git.rs+14−12
@@ -43,6 +43,7 @@ mod connect_message { · 42 unmodified lines
4343
4444 use crate::fixture_bytes;
4545 use bstr::ByteSlice;
46+use git_transport::client::SetProgressHandlerBufRead;
4647 use git_transport::{
4748 client::{self, git, Transport},
4849 Protocol, Service,
@@ -94,33 +95,34 @@ fn handshake_v1_and_request() -> crate::Result { · 45 unmodified lines
9495 );
9596 drop(res);
9697
97− let writer = c.request(client::WriteMode::Binary, Vec::new(), None)?;
98+ let writer = c.request(client::WriteMode::Binary, Vec::new())?;
9899 assert_eq!(writer.into_read().lines().next().expect("exactly one line")?, "NAK");
99100
100− let sidebands = Rc::new(RefCell::new(Vec::<String>::new()));
101101 let mut writer = c.request(
102102 client::WriteMode::OneLFTerminatedLinePerWriteCall,
103103 vec![client::MessageKind::Flush, client::MessageKind::Text(b"done")],
104− Some(Box::new({
105− let sb = sidebands.clone();
106− move |is_err, data| {
107− assert!(!is_err);
108− sb.deref()
109− .borrow_mut()
110− .push(std::str::from_utf8(data).expect("valid utf8").to_owned())
111− }
112− })),
113104 )?;
114105
115106 writer.write_all(b"hello")?;
116107 writer.write_all(b"world")?;
108+
117109 let mut reader = writer.into_read();
110+ let messages = Rc::new(RefCell::new(Vec::<String>::new()));
111+ reader.set_progress_handler(Some(Box::new({
112+ let sb = messages.clone();
113+ move |is_err, data| {
114+ assert!(!is_err);
115+ sb.deref()
116+ .borrow_mut()
117+ .push(std::str::from_utf8(data).expect("valid utf8").to_owned())
118+ }
119+ })));
118120 let mut pack = Vec::new();
119121 reader.read_to_end(&mut pack)?;
120122 assert_eq!(pack.len(), 876, "we receive the whole pack…");
121123
122124 drop(reader);
123− let sidebands = Rc::try_unwrap(sidebands).expect("no other handle").into_inner();
125+ let sidebands = Rc::try_unwrap(messages).expect("no other handle").into_inner();
124126 assert_eq!(sidebands.len(), 6, "…along with some status messages");
125127 assert_eq!(
126128 out.as_slice().as_bstr(),
git-transport/tests/client/http.rs+22−2
@@ -1,10 +1,14 @@
11 use crate::fixture_bytes;
22 use bstr::{ByteSlice, ByteVec};
3+use git_transport::client::SetProgressHandlerBufRead;
34 use git_transport::{client, client::http, client::SetServiceResponse, client::Transport, Protocol, Service};
45 use std::{
6+ cell::RefCell,
57 error::Error,
68 io::{self, BufRead, Read, Write},
79 net::SocketAddr,
10+ ops::Deref,
11+ rc::Rc,
812 time::Duration,
913 };
1014
@@ -258,7 +262,6 @@ fn clone_v1() -> crate::Result { · 247 unmodified lines
258262 client::WriteMode::OneLFTerminatedLinePerWriteCall,
259263 // vec![client::MessageKind::Flush, client::MessageKind::Text(b"done")],
260264 Vec::new(),
261− None,
262265 )?;
263266 eprintln!("about to write data");
264267 writer.write_all(b"hello")?;
@@ -267,8 +270,25 @@ fn clone_v1() -> crate::Result { · 2 unmodified lines
267270 let mut reader = writer.into_read();
268271 let mut line = String::new();
269272 reader.read_line(&mut line)?;
270− // TODO: switch to binary with progress and
273+ assert_eq!(line, "NAK", "we received a NAK in text mode");
271274
275+ let messages = Rc::new(RefCell::new(Vec::<String>::new()));
276+ reader.set_progress_handler(Some(Box::new({
277+ let sb = messages.clone();
278+ move |is_err, data| {
279+ assert!(!is_err);
280+ sb.deref()
281+ .borrow_mut()
282+ .push(std::str::from_utf8(data).expect("valid utf8").to_owned())
283+ }
284+ })));
285+ let mut pack = Vec::new();
286+ reader.read_to_end(&mut pack)?;
287+ assert_eq!(pack.len(), 876, "we receive the whole pack…");
288+ drop(reader);
289+
290+ let sidebands = Rc::try_unwrap(messages).expect("no other handle").into_inner();
291+ assert_eq!(sidebands.len(), 6);
272292 assert_eq!(
273293 server.received_as_string(),
274294 "hello world with packet lines and on-drop flush and done"