gix_protocol/fetch/arguments/
blocking_io.rs1use std::io::Write;
2
3use gix_transport::client::{
4 self,
5 blocking_io::{ExtendedBufRead, Transport, TransportV2Ext},
6};
7
8use crate::{fetch::Arguments, Command};
9
10impl Arguments {
11 pub fn send<'a, T: Transport + 'a>(
13 &mut self,
14 transport: &'a mut T,
15 add_done_argument: bool,
16 ) -> Result<Box<dyn ExtendedBufRead<'a> + Unpin + 'a>, client::Error> {
17 if self.haves.is_empty() {
18 assert!(add_done_argument, "If there are no haves, is_done must be true.");
19 }
20 match self.version {
21 gix_transport::Protocol::V0 | gix_transport::Protocol::V1 => {
22 let (on_into_read, retained_state) = self.prepare_v1(
23 transport.connection_persists_across_multiple_requests(),
24 add_done_argument,
25 )?;
26 let mut line_writer = transport.request(
27 client::WriteMode::OneLfTerminatedLinePerWriteCall,
28 on_into_read,
29 self.trace,
30 )?;
31 let had_args = !self.args.is_empty();
32 for arg in self.args.drain(..) {
33 line_writer.write_all(&arg)?;
34 }
35 if had_args {
36 line_writer.write_message(client::MessageKind::Flush)?;
37 }
38 for line in self.haves.drain(..) {
39 line_writer.write_all(&line)?;
40 }
41 if let Some(next_args) = retained_state {
42 self.args = next_args;
43 }
44 Ok(line_writer.into_read()?)
45 }
46 gix_transport::Protocol::V2 => {
47 let retained_state = self.args.clone();
48 self.args.append(&mut self.haves);
49 if add_done_argument {
50 self.args.push("done".into());
51 }
52 transport.invoke(
53 Command::Fetch.as_str(),
54 self.features.iter().filter(|(_, v)| v.is_some()).cloned(),
55 Some(std::mem::replace(&mut self.args, retained_state).into_iter()),
56 self.trace,
57 )
58 }
59 }
60 }
61}