summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKornel <kornel@geekhood.net>2020-04-11 19:27:17 +0100
committerKornel <kornel@geekhood.net>2020-04-11 19:27:17 +0100
commit78f6d187519ff8740ba438e6e09ae2cd544955cd (patch)
tree9e7a0602e2ae0a1d95f892935d073cd81824d789
parentb89e65cc4e2bb9063371e91c4098e033ea57f385 (diff)
Fix github wrapperHEADmaster
-rw-r--r--github_info/src/lib_github.rs15
-rw-r--r--github_v3/Cargo.toml2
-rw-r--r--github_v3/src/lib.rs31
3 files changed, 35 insertions, 13 deletions
diff --git a/github_info/src/lib_github.rs b/github_info/src/lib_github.rs
index d3b1cea..375153f 100644
--- a/github_info/src/lib_github.rs
+++ b/github_info/src/lib_github.rs
@@ -5,7 +5,6 @@ use std::path::Path;
use github_v3::StatusCode;
use serde::{Deserialize, Serialize};
-use urlencoding::encode;
mod model;
pub use crate::model::*;
@@ -88,9 +87,9 @@ impl GitHub {
return Ok(Some(vec![user]));
}
}
- let enc_email = encode(email);
self.get_cached(&self.emails, (email, ""), |client| client.get()
- .path(&format!("search/users?q=in:email%20{}", enc_email))
+ .path("search/users")
+ .query("q=in:email%20").arg(email)
.send(), |res: SearchResults<User>| {
println!("Found {} = {:#?}", email, res.items);
res.items
@@ -128,9 +127,8 @@ impl GitHub {
pub async fn releases(&self, repo: &SimpleRepo, as_of_version: &str) -> CResult<Option<Vec<GitHubRelease>>> {
let key = format!("release/{}/{}", repo.owner, repo.repo);
- let path = format!("repos/{}/{}/releases", repo.owner, repo.repo);
self.get_cached(&self.releases, (&key, as_of_version), |client| client.get()
- .path(&path)
+ .path("repos").arg(&repo.owner).arg(&repo.repo).path("releases")
.send(), id).await.map_err(|e| e.context("releases"))
}
@@ -164,10 +162,9 @@ impl GitHub {
pub async fn contributors(&self, repo: &SimpleRepo, as_of_version: &str) -> CResult<Option<Vec<UserContrib>>> {
let path = format!("repos/{}/{}/stats/contributors", repo.owner, repo.repo);
let key = (path.as_str(), as_of_version);
- let callback = |client: &github_v3::Client| {
- client.get().path(&path).send()
- };
- self.get_cached(&self.contribs, key, callback, id).await
+ self.get_cached(&self.contribs, key, |client: &github_v3::Client| {
+ client.get().path("repos").arg(&repo.owner).arg(&repo.repo).path("stats/contributors").send()
+ }, id).await
}
async fn get_cached<F, P, B, R, A>(&self, cache: &TempCache<(String, Option<R>)>, key: (&str, &str), cb: F, postproc: P) -> CResult<Option<R>>
diff --git a/github_v3/Cargo.toml b/github_v3/Cargo.toml
index 5f5247c..5506603 100644
--- a/github_v3/Cargo.toml
+++ b/github_v3/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "github_v3"
description = "Async GitHub API v3 client"
-version = "0.3.1"
+version = "0.3.2"
authors = ["Kornel <kornel@geekhood.net>"]
keywords = ["github", "restful", "api", "async"]
categories = ["web-programming", "web-programming::http-client"]
diff --git a/github_v3/src/lib.rs b/github_v3/src/lib.rs
index a5fc31a..79c5a06 100644
--- a/github_v3/src/lib.rs
+++ b/github_v3/src/lib.rs
@@ -61,29 +61,53 @@ impl Response {
pub struct Builder {
client: Arc<ClientInner>,
url: String,
+ query_string_started: bool,
}
impl Builder {
/// Add a constant path to the request, e.g. `.path("users")`
///
+ /// Inner slashes are OK, but the string must not start or end with a slash.
+ ///
+ /// Panics if query string has been added.
+ ///
/// It's appended raw, so must be URL-safe.
pub fn path(mut self, url_part: &'static str) -> Self {
debug_assert_eq!(url_part, url_part.trim_matches('/'));
+ assert!(!self.query_string_started);
self.url.push('/');
self.url.push_str(url_part);
self
}
- /// Add a user-supplied argument to the request path, e.g. `.path("users").arg(username)`
+ /// Add a user-supplied argument to the request path, e.g. `.path("users").arg(username)`,
+ /// or after a call to query(), starts adding fragments to the query string with no delimiters.
///
/// The arg is URL-escaped, so it's safe to use any user-supplied data.
pub fn arg(mut self, arg: &str) -> Self {
- self.url.push('/');
+ if !self.query_string_started {
+ self.url.push('/');
+ }
self.url.push_str(&urlencoding::encode(arg));
self
}
+ /// Add a raw unescaped query string. The string must *not* start with `?`
+ ///
+ /// ```rust
+ /// # Client::new(None)
+ /// .get().path("search/users").query("q=").arg(somestring)
+ /// ```
+ pub fn query(mut self, query_string: &str) -> Self {
+ debug_assert!(!query_string.starts_with('?'));
+ debug_assert!(!query_string.starts_with('&'));
+ self.url.push(if self.query_string_started {'&'} else {'?'});
+ self.url.push_str(query_string);
+ self.query_string_started = true;
+ self
+ }
+
/// Make the request
pub async fn send(self) -> Result<Response, GHError> {
let res = self.client.raw_get(&self.url).await?;
@@ -135,11 +159,12 @@ impl Client {
/// Make a new request to the API.
pub fn get(&self) -> Builder {
- let mut url = String::with_capacity(60);
+ let mut url = String::with_capacity(100);
url.push_str("https://api.github.com");
Builder {
client: self.inner.clone(),
url,
+ query_string_started: false,
}
}
}