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