mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-22 10:26:30 +00:00
move RetrieveFileAtPath
to src/interactors/mod
Also add functions to both the `github` and `gitlab` modules for constructing the Uri to the manifest
This commit is contained in:
parent
194be9c9b5
commit
dff2a92aa5
3 changed files with 87 additions and 40 deletions
|
@ -11,46 +11,14 @@ use ::models::repo::{Repository, RepoPath};
|
|||
const GITHUB_API_BASE_URI: &'static str = "https://api.github.com";
|
||||
const GITHUB_USER_CONTENT_BASE_URI: &'static str = "https://raw.githubusercontent.com";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RetrieveFileAtPath<S>(pub S);
|
||||
|
||||
impl<S> Service for RetrieveFileAtPath<S>
|
||||
where S: Service<Request=Request, Response=Response, Error=HyperError> + Clone + 'static,
|
||||
S::Future: 'static
|
||||
{
|
||||
type Request = (RepoPath, RelativePathBuf);
|
||||
type Response = String;
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
let service = self.0.clone();
|
||||
|
||||
let (repo_path, path) = req;
|
||||
pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result<Uri, ::hyper::error::UriError> {
|
||||
let path_str: &str = path.as_ref();
|
||||
let uri_future = format!("{}/{}/{}/HEAD/{}",
|
||||
Ok(format!("{}/{}/{}/HEAD/{}",
|
||||
GITHUB_USER_CONTENT_BASE_URI,
|
||||
repo_path.qual.as_ref(),
|
||||
repo_path.name.as_ref(),
|
||||
path_str
|
||||
).parse::<Uri>().into_future().from_err();
|
||||
|
||||
Box::new(uri_future.and_then(move |uri| {
|
||||
let request = Request::new(Method::Get, uri.clone());
|
||||
|
||||
service.call(request).from_err().and_then(move |response| {
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
future::Either::A(future::err(format_err!("Status code {} for URI {}", status, uri)))
|
||||
} else {
|
||||
let body_future = response.body().concat2().from_err();
|
||||
let decode_future = body_future
|
||||
.and_then(|body| String::from_utf8(body.to_vec()).map_err(|err| err.into()));
|
||||
future::Either::B(decode_future)
|
||||
}
|
||||
})
|
||||
}))
|
||||
}
|
||||
).parse::<Uri>()?)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
|
23
src/interactors/gitlab.rs
Normal file
23
src/interactors/gitlab.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use hyper::Uri;
|
||||
use relative_path::RelativePathBuf;
|
||||
|
||||
use ::models::repo::RepoPath;
|
||||
|
||||
const GITLAB_USER_CONTENT_BASE_URI: &'static str = "https://gitlab.com";
|
||||
|
||||
pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result<Uri, ::hyper::error::UriError> {
|
||||
let path_str: &str = path.as_ref();
|
||||
// gitlab will return a 308 if the Uri ends with, say, `.../raw/master//Cargo.toml`, so make
|
||||
// sure that last slash isn't doubled
|
||||
let slash_path = if path_str.starts_with("/") {
|
||||
&path_str[1..]
|
||||
} else {
|
||||
path_str
|
||||
};
|
||||
format!("{}/{}/{}/raw/master/{}",
|
||||
GITLAB_USER_CONTENT_BASE_URI,
|
||||
repo_path.qual.as_ref(),
|
||||
repo_path.name.as_ref(),
|
||||
slash_path
|
||||
).parse::<Uri>()
|
||||
}
|
|
@ -1,2 +1,58 @@
|
|||
use failure::Error;
|
||||
use futures::{Future, IntoFuture, Stream, future};
|
||||
use hyper::{Error as HyperError, Method, Request, Response};
|
||||
use relative_path::RelativePathBuf;
|
||||
use tokio_service::Service;
|
||||
|
||||
use ::models::repo::{RepoSite, RepoPath};
|
||||
|
||||
pub mod crates;
|
||||
pub mod github;
|
||||
pub mod gitlab;
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RetrieveFileAtPath<S>(pub S);
|
||||
|
||||
impl<S> Service for RetrieveFileAtPath<S>
|
||||
where S: Service<Request=Request, Response=Response, Error=HyperError> + Clone + 'static,
|
||||
S::Future: 'static
|
||||
{
|
||||
type Request = (RepoPath, RelativePathBuf);
|
||||
type Response = String;
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
let service = self.0.clone();
|
||||
|
||||
let (repo_path, path) = req;
|
||||
let uri = match &repo_path.site {
|
||||
&RepoSite::Github => {
|
||||
github::get_manifest_uri(&repo_path, &path)
|
||||
},
|
||||
&RepoSite::Gitlab => {
|
||||
gitlab::get_manifest_uri(&repo_path, &path)
|
||||
},
|
||||
};
|
||||
let uri_future = uri.into_future().from_err();
|
||||
|
||||
Box::new(uri_future.and_then(move |uri| {
|
||||
let request = Request::new(Method::Get, uri.clone());
|
||||
|
||||
service.call(request).from_err().and_then(move |response| {
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
future::Either::A(future::err(format_err!("Status code {} for URI {}", status, uri)))
|
||||
} else {
|
||||
let body_future = response.body().concat2().from_err();
|
||||
let decode_future = body_future
|
||||
.and_then(|body| String::from_utf8(body.to_vec()).map_err(|err| err.into()));
|
||||
future::Either::B(decode_future)
|
||||
}
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue