sley_remote/
capabilities.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct TransportCapabilities {
9 pub http_fetch: bool,
11 pub http_push: bool,
13 pub http_protocol_v2_discovery: bool,
15 pub http_protocol_v2_fetch: bool,
17 pub shallow_fetch: bool,
19 pub ssh_fetch: bool,
21 pub ssh_push: bool,
22 pub ssh_clone: bool,
24 pub git_fetch: bool,
26 pub git_push: bool,
27 pub git_clone: bool,
28 pub bundle_fetch: bool,
30 pub local_fetch: bool,
32 pub local_push: bool,
33 pub credential_helper: bool,
35 pub thin_pack_push: bool,
37 pub sha256_http: bool,
39 pub sha256_ssh: bool,
41}
42
43pub const HTTP_PROTOCOL_V2_FETCH: bool = true;
45pub const SSH_CLONE_SUPPORTED: bool = true;
47pub const BUNDLE_FETCH_SUPPORTED: bool = true;
49pub const THIN_PACK_PUSH_SUPPORTED: bool = true;
51
52impl TransportCapabilities {
53 pub const fn current() -> Self {
55 Self {
56 http_fetch: cfg!(feature = "http"),
57 http_push: cfg!(feature = "http"),
58 http_protocol_v2_discovery: cfg!(feature = "http"),
59 http_protocol_v2_fetch: cfg!(feature = "http") && HTTP_PROTOCOL_V2_FETCH,
60 shallow_fetch: true,
61 ssh_fetch: true,
62 ssh_push: true,
63 ssh_clone: SSH_CLONE_SUPPORTED,
64 git_fetch: true,
65 git_push: true,
66 git_clone: true,
67 bundle_fetch: BUNDLE_FETCH_SUPPORTED,
68 local_fetch: true,
69 local_push: true,
70 credential_helper: true,
71 thin_pack_push: THIN_PACK_PUSH_SUPPORTED,
72 sha256_http: cfg!(feature = "http"),
73 sha256_ssh: true,
74 }
75 }
76
77 pub fn supports_native_push(&self, transport: RemoteTransportKind) -> bool {
79 match transport {
80 RemoteTransportKind::Http => self.http_push,
81 RemoteTransportKind::Ssh => self.ssh_push,
82 RemoteTransportKind::Git => self.git_push,
83 RemoteTransportKind::Local => self.local_push,
84 RemoteTransportKind::Bundle => false,
85 }
86 }
87
88 pub fn supports_shallow(&self, transport: RemoteTransportKind) -> bool {
90 match transport {
91 RemoteTransportKind::Http | RemoteTransportKind::Ssh | RemoteTransportKind::Git => {
92 self.shallow_fetch
93 }
94 RemoteTransportKind::Local | RemoteTransportKind::Bundle => false,
95 }
96 }
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum RemoteTransportKind {
102 Http,
103 Ssh,
104 Git,
105 Local,
106 Bundle,
107}
108
109#[cfg(all(test, not(feature = "http")))]
110mod tests {
111 use super::TransportCapabilities;
112
113 #[test]
114 fn ssh_only_build_disables_http_fetch_capability() {
115 let caps = TransportCapabilities::current();
116 assert!(!caps.http_fetch);
117 assert!(!caps.http_push);
118 assert!(!caps.http_protocol_v2_discovery);
119 assert!(!caps.http_protocol_v2_fetch);
120 assert!(!caps.sha256_http);
121 assert!(caps.ssh_fetch);
122 }
123}
124
125impl RemoteTransportKind {
126 pub fn from_url_scheme(url: &str) -> Option<Self> {
127 if url.starts_with("http://") || url.starts_with("https://") {
128 return Some(Self::Http);
129 }
130 if url.starts_with("git://") {
131 return Some(Self::Git);
132 }
133 if url.starts_with("ssh://")
134 || url.starts_with("git@")
135 || url.contains(':') && !url.contains("://")
136 {
137 return Some(Self::Ssh);
138 }
139 if url.starts_with("file://") || url.starts_with('/') || url.starts_with("./") {
140 return Some(Self::Local);
141 }
142 if url.ends_with(".bundle") {
143 return Some(Self::Bundle);
144 }
145 None
146 }
147}