Skip to content

Commit 5bef0a0

Browse files
committed
FAIL: try to make the transport configurable after being boxed, but… (#450)
…that would force it to be 'static, which is something we excplicitly cannot have. We need references to be contained within, if I remember correctly.
1 parent 0dc7206 commit 5bef0a0

File tree

6 files changed

+58
-3
lines changed

6 files changed

+58
-3
lines changed

git-repository/src/remote/connection/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mod access {
2424
remote::{connection::CredentialsFn, Connection},
2525
Remote,
2626
};
27+
use std::any::Any;
2728

2829
/// Builder
2930
impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> {
@@ -62,6 +63,31 @@ mod access {
6263
pub fn remote(&self) -> &Remote<'repo> {
6364
self.remote
6465
}
66+
67+
/// Return the connection's transport.
68+
pub fn transport(&self) -> &T {
69+
&self.transport
70+
}
71+
}
72+
73+
/// Access to the transport if it can be downcast to a particular type.
74+
impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P>
75+
where
76+
T: crate::protocol::transport::client::Transport + 'static,
77+
{
78+
/// Try to cast our transport `T` into `U`, and pass it to `f` to allow any kind of configuration.
79+
///
80+
/// Note that if the case fails and `f` is not called at all, `false` is returned.
81+
pub fn configure_transport<U: 'static, E>(
82+
&mut self,
83+
f: impl FnOnce(&mut U) -> Result<(), E>,
84+
) -> Result<bool, E> {
85+
let transport = (&mut self.transport) as &mut dyn Any;
86+
match transport.downcast_mut::<U>() {
87+
Some(transport) => f(transport).map(|_| true),
88+
None => Ok(false),
89+
}
90+
}
6591
}
6692
}
6793

git-repository/src/remote/connection/ref_map.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ where
134134
&mut credentials_storage
135135
}
136136
};
137+
let transport = &mut self.transport;
137138
let mut outcome =
138-
git_protocol::fetch::handshake(&mut self.transport, authenticate, extra_parameters, &mut self.progress)
139-
.await?;
139+
git_protocol::fetch::handshake(&mut *transport, authenticate, extra_parameters, &mut self.progress).await?;
140140
let refs = match outcome.refs.take() {
141141
Some(refs) => refs,
142142
None => {
143143
let specs = &self.remote.fetch_specs;
144144
git_protocol::fetch::refs(
145-
&mut self.transport,
145+
transport,
146146
outcome.server_protocol_version,
147147
&outcome.capabilities,
148148
|_capabilities, arguments, _features| {

git-transport/src/client/blocking_io/file.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::Any;
12
use std::process::{self, Command, Stdio};
23

34
use bstr::{BString, ByteSlice};
@@ -83,6 +84,10 @@ impl SpawnProcessOnDemand {
8384
}
8485

8586
impl client::TransportWithoutIO for SpawnProcessOnDemand {
87+
fn as_any_mut(&mut self) -> &mut dyn Any {
88+
self
89+
}
90+
8691
fn request(
8792
&mut self,
8893
write_mode: WriteMode,

git-transport/src/client/blocking_io/http/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::Any;
12
use std::{
23
borrow::Cow,
34
convert::Infallible,
@@ -99,6 +100,10 @@ fn append_url(base: &str, suffix: &str) -> String {
99100
}
100101

101102
impl<H: Http> client::TransportWithoutIO for Transport<H> {
103+
fn as_any_mut(&mut self) -> &mut dyn Any {
104+
self
105+
}
106+
102107
fn set_identity(&mut self, identity: git_sec::identity::Account) -> Result<(), client::Error> {
103108
self.identity = Some(identity);
104109
Ok(())

git-transport/src/client/git/blocking_io.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::Any;
12
use std::io::Write;
23

34
use bstr::BString;
@@ -13,6 +14,10 @@ where
1314
R: std::io::Read,
1415
W: std::io::Write,
1516
{
17+
fn as_any_mut(&mut self) -> &mut dyn Any {
18+
self
19+
}
20+
1621
fn request(
1722
&mut self,
1823
write_mode: client::WriteMode,

git-transport/src/client/traits.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::Any;
12
use std::ops::{Deref, DerefMut};
23

34
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
@@ -7,6 +8,11 @@ use crate::{client::Error, Protocol};
78
/// This trait represents all transport related functions that don't require any input/output to be done which helps
89
/// implementation to share more code across blocking and async programs.
910
pub trait TransportWithoutIO {
11+
/// Cast this type as dyn trait to allow casting it back to a known concrete type.
12+
///
13+
/// This is useful for configuration after a boxed transport implementation has been crated.
14+
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
15+
1016
/// If the handshake or subsequent reads failed with [std::io::ErrorKind::PermissionDenied], use this method to
1117
/// inform the transport layer about the identity to use for subsequent calls.
1218
/// If authentication continues to fail even with an identity set, consider communicating this to the provider
@@ -50,6 +56,10 @@ pub trait TransportWithoutIO {
5056

5157
// Would be nice if the box implementation could auto-forward to all implemented traits.
5258
impl<T: TransportWithoutIO + ?Sized> TransportWithoutIO for Box<T> {
59+
fn as_any_mut(&mut self) -> &mut dyn Any {
60+
self
61+
}
62+
5363
fn set_identity(&mut self, identity: git_sec::identity::Account) -> Result<(), Error> {
5464
self.deref_mut().set_identity(identity)
5565
}
@@ -73,6 +83,10 @@ impl<T: TransportWithoutIO + ?Sized> TransportWithoutIO for Box<T> {
7383
}
7484

7585
impl<T: TransportWithoutIO + ?Sized> TransportWithoutIO for &mut T {
86+
fn as_any_mut(&mut self) -> &mut dyn Any {
87+
self
88+
}
89+
7690
fn set_identity(&mut self, identity: git_sec::identity::Account) -> Result<(), Error> {
7791
self.deref_mut().set_identity(identity)
7892
}

0 commit comments

Comments
 (0)