Skip to content

Commit 0064d91

Browse files
committed
add support for JSON request bodies
1 parent ead89db commit 0064d91

3 files changed

Lines changed: 64 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rand = "0.3.16"
88
clap = "2.26.2"
99
hyper = "0.11"
1010
futures = "0.1"
11+
maplit = "0.1.4"
1112
tokio-core = "0.1"
1213
url = "1.5.1"
1314
serde = "1.0"

src/main.rs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ extern crate clap;
22
extern crate futures;
33
extern crate hyper;
44
extern crate serde;
5-
extern crate serde_json;
6-
#[macro_use]
7-
extern crate serde_derive;
85
extern crate tokio_core;
96
extern crate url;
107

8+
#[macro_use] extern crate maplit;
9+
#[macro_use] extern crate serde_json;
10+
#[macro_use] extern crate serde_derive;
11+
1112
use clap::{Arg, ArgMatches, App};
1213
use futures::{Future, Stream};
1314
use hyper::{Client, Method, Request, Uri};
1415
use hyper::header;
1516
use hyper::header::Authorization;
17+
use std::collections::HashMap;
1618
use std::option::Option::*;
1719
use std::str::FromStr;
1820
use tokio_core::reactor::Core;
@@ -26,21 +28,48 @@ fn main() {
2628
let request = client.get_project_list();
2729
match client.run(request) {
2830
Ok(projects) => {
31+
println!("All projects:");
2932
for project in projects {
30-
println!("{:?}", project);
33+
println!(" {:?}", project);
3134
}
3235
},
3336
Err(e) => {
3437
println!("Error in request: {:?}", e);
3538
}
3639
}
40+
41+
println!("");
42+
43+
let query_projects = client.query_projects(&ApiProjectFilter {
44+
name: Some("scrape"),
45+
metadata: Some(hashmap!{
46+
"Owner" => "dylan"
47+
})
48+
});
49+
match client.run(query_projects) {
50+
Ok(projects) => {
51+
println!("Projects with a name matching 'scrape' and owned by 'dylan':");
52+
for project in projects {
53+
println!(" {:?}", project);
54+
}
55+
},
56+
Err(e) => {
57+
println!("Error in request: {:?}", e)
58+
}
59+
}
3760
},
3861
Err(ConfigError::MissingAuth) => println!("Authorization info missing or incomplete. Either an API Key or a Username + Password must be provided"),
3962
Err(ConfigError::MissingUrl) => println!("Missing the Base URL"),
4063
Err(ConfigError::InvalidUrl) => println!("Invalid Base URL"),
4164
};
4265
}
4366

67+
#[derive(Serialize)]
68+
struct ApiProjectFilter<'a> {
69+
name: Option<&'a str>,
70+
metadata: Option<HashMap<&'a str, &'a str>>
71+
}
72+
4473
#[derive(Deserialize, Debug)]
4574
struct ApiProject {
4675
id: u32,
@@ -59,6 +88,22 @@ struct ApiClient<'a> {
5988
client: Client<hyper::client::HttpConnector, hyper::Body>
6089
}
6190

91+
enum ReqBody {
92+
Json(serde_json::Value),
93+
// TODO: support multipart forms
94+
}
95+
96+
impl From<ReqBody> for hyper::Body {
97+
fn from(body: ReqBody) -> hyper::Body {
98+
match body {
99+
ReqBody::Json(value) => {
100+
let raw_body = serde_json::to_vec(&value).unwrap();
101+
hyper::Body::from(raw_body)
102+
},
103+
}
104+
}
105+
}
106+
62107
impl <'a> ApiClient<'a> {
63108
fn new(config: &'a ClientConfig) -> std::io::Result<ApiClient> {
64109
Core::new().map(|core| {
@@ -75,6 +120,13 @@ impl <'a> ApiClient<'a> {
75120
self.request_json(Method::Get, &["x", "projects"])
76121
}
77122

123+
fn query_projects<'f>(&self, filter: &'f ApiProjectFilter) -> BoxedClientFuture<Vec<ApiProject>> {
124+
let body = ReqBody::Json(json!({
125+
"filter": filter
126+
}));
127+
self.request_json_with_body(Method::Post, &["x", "projects", "query"], Some(body))
128+
}
129+
78130
/// Underlying method for creating a request to be sent to Code Dx.
79131
///
80132
/// Accepts a `method` (GET, POST, etc)

0 commit comments

Comments
 (0)