gix_protocol/handshake/
mod.rs1use bstr::BString;
2
3pub mod refs;
5
6#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub enum Ref {
10 Peeled {
12 full_ref_name: BString,
14 tag: gix_hash::ObjectId,
16 object: gix_hash::ObjectId,
18 },
19 Direct {
21 full_ref_name: BString,
23 object: gix_hash::ObjectId,
25 },
26 Symbolic {
28 full_ref_name: BString,
30 target: BString,
36 tag: Option<gix_hash::ObjectId>,
40 object: gix_hash::ObjectId,
42 },
43 Unborn {
46 full_ref_name: BString,
48 target: BString,
50 },
51}
52
53#[cfg(feature = "handshake")]
54pub(crate) mod hero {
55 use crate::handshake::Ref;
56
57 #[derive(Default, Debug, Clone)]
59 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60 pub struct Handshake {
61 pub server_protocol_version: gix_transport::Protocol,
63 pub refs: Option<Vec<Ref>>,
65 pub v1_shallow_updates: Option<Vec<crate::fetch::response::ShallowUpdate>>,
68 pub capabilities: gix_transport::client::Capabilities,
70 }
71
72 #[cfg(feature = "fetch")]
73 mod fetch {
74 #[cfg(feature = "async-client")]
75 use crate::transport::client::async_io::Transport;
76 #[cfg(feature = "blocking-client")]
77 use crate::transport::client::blocking_io::Transport;
78 use crate::Handshake;
79 use gix_features::progress::Progress;
80 use std::borrow::Cow;
81
82 impl Handshake {
83 #[allow(clippy::result_large_err)]
86 #[maybe_async::maybe_async]
87 pub async fn fetch_or_extract_refmap<T>(
88 &mut self,
89 mut progress: impl Progress,
90 transport: &mut T,
91 user_agent: (&'static str, Option<Cow<'static, str>>),
92 trace_packetlines: bool,
93 prefix_from_spec_as_filter_on_remote: bool,
94 refmap_context: crate::fetch::refmap::init::Context,
95 ) -> Result<crate::fetch::RefMap, crate::fetch::refmap::init::Error>
96 where
97 T: Transport,
98 {
99 Ok(match self.refs.take() {
100 Some(refs) => crate::fetch::RefMap::from_refs(refs, &self.capabilities, refmap_context)?,
101 None => {
102 crate::fetch::RefMap::fetch(
103 &mut progress,
104 &self.capabilities,
105 transport,
106 user_agent,
107 trace_packetlines,
108 prefix_from_spec_as_filter_on_remote,
109 refmap_context,
110 )
111 .await?
112 }
113 })
114 }
115 }
116 }
117}
118
119#[cfg(feature = "handshake")]
120mod error {
121 use bstr::BString;
122 use gix_transport::client;
123
124 use crate::{credentials, handshake::refs};
125
126 #[derive(Debug, thiserror::Error)]
128 #[allow(missing_docs)]
129 pub enum Error {
130 #[error("Failed to obtain credentials")]
131 Credentials(#[from] credentials::protocol::Error),
132 #[error("No credentials were returned at all as if the credential helper isn't functioning unknowingly")]
133 EmptyCredentials,
134 #[error("Credentials provided for \"{url}\" were not accepted by the remote")]
135 InvalidCredentials { url: BString, source: std::io::Error },
136 #[error(transparent)]
137 Transport(#[from] client::Error),
138 #[error("The transport didn't accept the advertised server version {actual_version:?} and closed the connection client side")]
139 TransportProtocolPolicyViolation { actual_version: gix_transport::Protocol },
140 #[error(transparent)]
141 ParseRefs(#[from] refs::parse::Error),
142 }
143
144 impl gix_transport::IsSpuriousError for Error {
145 fn is_spurious(&self) -> bool {
146 match self {
147 Error::Transport(err) => err.is_spurious(),
148 _ => false,
149 }
150 }
151 }
152}
153#[cfg(feature = "handshake")]
154pub use error::Error;
155
156#[cfg(any(feature = "blocking-client", feature = "async-client"))]
157#[cfg(feature = "handshake")]
158pub(crate) mod function;