Skip to content

Commit

Permalink
feat: connect() method is available in when async-std feature is …
Browse files Browse the repository at this point in the history
…set along with `async-client` (#450)

This makes some async support available even trough the base crate,
which otherwise would require establishing a connection (with a runtime
of choice) by hand.
  • Loading branch information
Byron committed Aug 15, 2022
1 parent f933ae3 commit f6a6a49
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 5 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ check: ## Build all code in suitable configurations
cd git-transport && cargo check \
&& cargo check --features blocking-client \
&& cargo check --features async-client \
&& cargo check --features async-client,async-std \
&& cargo check --features http-client-curl
cd git-transport && if cargo check --all-features 2>/dev/null; then false; else true; fi
cd git-protocol && cargo check \
Expand Down
4 changes: 4 additions & 0 deletions git-transport/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ curl = { version = "0.4", optional = true, features = ["static-curl", "static-ss
thiserror = "1.0.26"
base64 = { version = "0.13.0", optional = true }

## If used in conjunction with `async-client`, the `connect()` method will be come available along with supporting the git protocol over TCP,
## where the TCP stream is created using this crate.
async-std = { version = "1.12.0", optional = true }

document-features = { version = "0.2.0", optional = true }

[dev-dependencies]
Expand Down
41 changes: 41 additions & 0 deletions git-transport/src/client/async_io/connect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pub use crate::client::non_io_types::connect::Error;

#[cfg(any(feature = "async-std"))]
pub(crate) mod function {
use crate::client::git;
use crate::client::non_io_types::connect::Error;

/// A general purpose connector connecting to a repository identified by the given `url`.
///
/// This includes connections to
/// [git daemons][crate::client::git::connect()] only at the moment.
///
/// Use `desired_version` to set the desired protocol version to use when connecting, but note that the server may downgrade it.
pub async fn connect(
url: &[u8],
desired_version: crate::Protocol,
) -> Result<impl crate::client::Transport + Send, Error> {
let urlb = url;
let mut url = git_url::parse(urlb)?;
Ok(match url.scheme {
git_url::Scheme::Git => {
if url.user().is_some() {
return Err(Error::UnsupportedUrlTokens {
url: urlb.into(),
scheme: url.scheme,
});
}
let path = std::mem::take(&mut url.path);
git::Connection::new_tcp(
url.host().expect("host is present in url"),
url.port,
path,
desired_version,
)
.await
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?
}
scheme => return Err(Error::UnsupportedScheme(scheme)),
})
}
}
6 changes: 3 additions & 3 deletions git-transport/src/client/async_io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ mod traits;
pub use traits::{SetServiceResponse, Transport, TransportV2Ext};

///
pub mod connect {
pub use crate::client::non_io_types::connect::Error;
}
pub mod connect;
#[cfg(any(feature = "async-std"))]
pub use connect::function::connect;
2 changes: 1 addition & 1 deletion git-transport/src/client/blocking_io/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) mod function {
/// [git daemons][crate::client::git::connect()],
/// and if compiled in connections to [git repositories over https][crate::client::http::connect()].
///
/// Use `desired_version` to set the desired protocol version to use when connecting, but not that the server may downgrade it.
/// Use `desired_version` to set the desired protocol version to use when connecting, but note that the server may downgrade it.
pub fn connect(url: &[u8], desired_version: crate::Protocol) -> Result<Box<dyn Transport + Send>, Error> {
let urlb = url;
let mut url = git_url::parse(urlb)?;
Expand Down
34 changes: 34 additions & 0 deletions git-transport/src/client/git/async_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,37 @@ where
}
}
}

#[cfg(feature = "async-std")]
mod async_net {
use crate::client::git;
use crate::client::Error;
use async_std::net::TcpStream;
use std::time::Duration;

impl git::Connection<TcpStream, TcpStream> {
/// Create a new TCP connection using the `git` protocol of `desired_version`, and make a connection to `host`
/// at `port` for accessing the repository at `path` on the server side.
pub async fn new_tcp(
host: &str,
port: Option<u16>,
path: bstr::BString,
desired_version: crate::Protocol,
) -> Result<git::Connection<TcpStream, TcpStream>, Error> {
let read = async_std::io::timeout(
Duration::from_secs(5),
TcpStream::connect(&(host, port.unwrap_or(9418))),
)
.await?;
let write = read.clone();
Ok(git::Connection::new(
read,
write,
desired_version,
path,
None::<(String, _)>,
git::ConnectMode::Daemon,
))
}
}
}
5 changes: 4 additions & 1 deletion git-transport/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ impl Service {
pub mod client;

#[doc(inline)]
#[cfg(feature = "blocking-client")]
#[cfg(any(
feature = "blocking-client",
all(feature = "async-client", any(feature = "async-std"))
))]
pub use client::connect;

#[cfg(all(feature = "async-client", feature = "blocking-client"))]
Expand Down

0 comments on commit f6a6a49

Please sign in to comment.