diff --git a/src/main.rs b/src/main.rs
index 9607eb0..ff0cb70 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,6 +8,8 @@ use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::Path;
+mod template;
+
fn save
(p: P, data: &str) -> Result<()>
where
P: AsRef,
@@ -755,11 +757,13 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
/*
* Deal with any dependencies we require to produce this client.
*/
+ a("");
if ts.import_chrono {
- a("");
a("use chrono::prelude::*;");
- a("");
}
+ a("use serde::{Serialize, Deserialize};");
+ a("use anyhow::Result;"); /* XXX */
+ a("");
/*
* Declare named types we know about:
@@ -767,6 +771,7 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
for te in ts.id_to_entry.values() {
match &te.details {
TypeDetails::Object(omap) => {
+ a("#[derive(Serialize, Deserialize, Debug)]");
a(&format!("pub struct {} {{", te.name.as_deref().unwrap()));
for (name, tid) in omap.iter() {
a(&format!(" pub {}: {},", name, ts.render_type(tid)?));
@@ -785,10 +790,26 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
* Declare the client object:
*/
a("pub struct Client {");
+ a(" baseurl: String,");
+ a(" client: reqwest::Client,");
a("}");
a("");
a("impl Client {");
+ a(" pub fn new(baseurl: &str) -> Client {");
+ a(" let dur = std::time::Duration::from_secs(15);");
+ a(" let client = reqwest::ClientBuilder::new()");
+ a(" .connect_timeout(dur)");
+ a(" .timeout(dur)");
+ a(" .build()");
+ a(" .unwrap();");
+ a("");
+ a(" Client {");
+ a(" baseurl: baseurl.to_string(),");
+ a(" client,");
+ a(" }");
+ a(" }");
+ a("");
/*
* Generate a function for each Operation.
@@ -817,11 +838,11 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
let mut bounds: Vec = Vec::new();
- let body_param = if let Some(b) = &o.request_body {
+ let (body_param, body_func) = if let Some(b) = &o.request_body {
let b = b.item()?;
if b.is_binary()? {
bounds.push("B: Into".to_string());
- Some("B".to_string())
+ (Some("B".to_string()), Some("body".to_string()))
} else {
let mt = b.content_json()?;
if !mt.encoding.is_empty() {
@@ -830,13 +851,16 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
if let Some(s) = &mt.schema {
let tid = ts.select(None, s)?;
- Some(format!("&{}", ts.render_type(&tid)?))
+ (
+ Some(format!("&{}", ts.render_type(&tid)?)),
+ Some("json".to_string()),
+ )
} else {
bail!("media type encoding, no schema: {:#?}", mt);
}
}
} else {
- None
+ (None, None)
};
if bounds.is_empty() {
@@ -947,7 +971,27 @@ fn gen(api: &OpenAPI, ts: &mut TypeSpace) -> Result {
bail!("responses? {:#?}", o.responses);
}
- a(" unimplemented!();");
+ /*
+ * Generate the URL for the request.
+ */
+ let tmp = template::parse(p)?;
+ a(&tmp.compile());
+
+ /*
+ * Perform the request.
+ */
+ a(&format!(" let res = self.client.{}(url)",
+ m.to_lowercase()));
+ if let Some(f) = &body_func {
+ a(&format!(" .{}(body)", f));
+ }
+ a(" .send()");
+ a(" .await?");
+ a(" .error_for_status()?;"); /* XXX */
+
+ a("");
+
+ a(" Ok(res.json().await?)");
a(" }");
a("");