]> git.proxmox.com Git - rustc.git/blob - vendor/gix-protocol/src/fetch/arguments/async_io.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / vendor / gix-protocol / src / fetch / arguments / async_io.rs
1 use futures_lite::io::AsyncWriteExt;
2 use gix_transport::{client, client::TransportV2Ext};
3
4 use crate::{fetch::Arguments, Command};
5
6 impl Arguments {
7 /// Send fetch arguments to the server, and indicate this is the end of negotiations only if `add_done_argument` is present.
8 pub async fn send<'a, T: client::Transport + 'a>(
9 &mut self,
10 transport: &'a mut T,
11 add_done_argument: bool,
12 ) -> Result<Box<dyn client::ExtendedBufRead + Unpin + 'a>, client::Error> {
13 if self.haves.is_empty() {
14 assert!(add_done_argument, "If there are no haves, is_done must be true.");
15 }
16 match self.version {
17 gix_transport::Protocol::V0 | gix_transport::Protocol::V1 => {
18 let (on_into_read, retained_state) = self.prepare_v1(
19 transport.connection_persists_across_multiple_requests(),
20 add_done_argument,
21 )?;
22 let mut line_writer =
23 transport.request(client::WriteMode::OneLfTerminatedLinePerWriteCall, on_into_read)?;
24 let had_args = !self.args.is_empty();
25 for arg in self.args.drain(..) {
26 line_writer.write_all(&arg).await?;
27 }
28 if had_args {
29 line_writer.write_message(client::MessageKind::Flush).await?;
30 }
31 for line in self.haves.drain(..) {
32 line_writer.write_all(&line).await?;
33 }
34 if let Some(next_args) = retained_state {
35 self.args = next_args;
36 }
37 Ok(line_writer.into_read().await?)
38 }
39 gix_transport::Protocol::V2 => {
40 let retained_state = self.args.clone();
41 self.args.append(&mut self.haves);
42 if add_done_argument {
43 self.args.push("done".into());
44 }
45 transport
46 .invoke(
47 Command::Fetch.as_str(),
48 self.features.iter().filter(|(_, v)| v.is_some()).cloned(),
49 Some(std::mem::replace(&mut self.args, retained_state).into_iter()),
50 )
51 .await
52 }
53 }
54 }
55 }