improve rustdoc output for generated crates (#37)

This commit is contained in:
Adam Leventhal 2022-03-17 23:54:10 -07:00 committed by GitHub
parent b7bbb5cdff
commit 75348207d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1909 additions and 478 deletions

View File

@ -52,7 +52,8 @@ struct OperationMethod {
operation_id: String, operation_id: String,
method: String, method: String,
path: PathTemplate, path: PathTemplate,
doc_comment: Option<String>, summary: Option<String>,
description: Option<String>,
params: Vec<OperationParameter>, params: Vec<OperationParameter>,
responses: Vec<OperationResponse>, responses: Vec<OperationResponse>,
dropshot_paginated: Option<DropshotPagination>, dropshot_paginated: Option<DropshotPagination>,
@ -69,10 +70,11 @@ enum OperationParameterKind {
Body, Body,
} }
struct OperationParameter { struct OperationParameter {
/// Sanitize parameter name. /// Sanitized parameter name.
name: String, name: String,
/// Original parameter name provided by the API. /// Original parameter name provided by the API.
api_name: String, api_name: String,
description: Option<String>,
typ: OperationParameterType, typ: OperationParameterType,
kind: OperationParameterKind, kind: OperationParameterKind,
} }
@ -85,6 +87,10 @@ enum OperationParameterType {
struct OperationResponse { struct OperationResponse {
status_code: OperationResponseStatus, status_code: OperationResponseStatus,
typ: OperationResponseType, typ: OperationResponseType,
// TODO this isn't currently used because dropshot doesn't give us a
// particularly useful message here.
#[allow(dead_code)]
description: Option<String>,
} }
impl Eq for OperationResponse {} impl Eq for OperationResponse {}
@ -350,6 +356,7 @@ impl Generator {
Ok(OperationParameter { Ok(OperationParameter {
name: sanitize(&parameter_data.name, Case::Snake), name: sanitize(&parameter_data.name, Case::Snake),
api_name: parameter_data.name.clone(), api_name: parameter_data.name.clone(),
description: parameter_data.description.clone(),
typ: OperationParameterType::Type(typ), typ: OperationParameterType::Type(typ),
kind: OperationParameterKind::Path, kind: OperationParameterKind::Path,
}) })
@ -389,6 +396,7 @@ impl Generator {
Ok(OperationParameter { Ok(OperationParameter {
name: sanitize(&parameter_data.name, Case::Snake), name: sanitize(&parameter_data.name, Case::Snake),
api_name: parameter_data.name.clone(), api_name: parameter_data.name.clone(),
description: parameter_data.description.clone(),
typ: OperationParameterType::Type(typ), typ: OperationParameterType::Type(typ),
kind: OperationParameterKind::Query( kind: OperationParameterKind::Query(
parameter_data.required, parameter_data.required,
@ -430,6 +438,7 @@ impl Generator {
raw_params.push(OperationParameter { raw_params.push(OperationParameter {
name: "body".to_string(), name: "body".to_string(),
api_name: "body".to_string(), api_name: "body".to_string(),
description: b.description.clone(),
typ, typ,
kind: OperationParameterKind::Body, kind: OperationParameterKind::Body,
}); });
@ -585,7 +594,17 @@ impl Generator {
success = true; success = true;
} }
Ok(OperationResponse { status_code, typ }) let description = if response.description.is_empty() {
None
} else {
Some(response.description.clone())
};
Ok(OperationResponse {
status_code,
typ,
description,
})
}) })
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
@ -597,6 +616,7 @@ impl Generator {
responses.push(OperationResponse { responses.push(OperationResponse {
status_code: OperationResponseStatus::Range(2), status_code: OperationResponseStatus::Range(2),
typ: OperationResponseType::Raw, typ: OperationResponseType::Raw,
description: None,
}); });
} }
@ -607,7 +627,11 @@ impl Generator {
operation_id: sanitize(operation_id, Case::Snake), operation_id: sanitize(operation_id, Case::Snake),
method: method.to_string(), method: method.to_string(),
path: tmp, path: tmp,
doc_comment: operation.description.clone(), summary: operation.summary.clone().filter(|s| !s.is_empty()),
description: operation
.description
.clone()
.filter(|s| !s.is_empty()),
params: raw_params, params: raw_params,
responses, responses,
dropshot_paginated, dropshot_paginated,
@ -811,18 +835,7 @@ impl Generator {
_ => quote! { _ => Err(Error::UnexpectedResponse(response)), }, _ => quote! { _ => Err(Error::UnexpectedResponse(response)), },
}; };
// TODO document parameters let doc_comment = make_doc_comment(method);
let doc_comment = format!(
"{}{}: {} {}",
method
.doc_comment
.as_ref()
.map(|s| format!("{}\n\n", s))
.unwrap_or_else(String::new),
method.operation_id,
method.method.to_ascii_uppercase(),
method.path.to_string(),
);
let pre_hook = self.pre_hook.as_ref().map(|hook| { let pre_hook = self.pre_hook.as_ref().map(|hook| {
quote! { quote! {
@ -956,17 +969,7 @@ impl Generator {
let item_type = item.ident(); let item_type = item.ident();
// TODO document parameters // TODO document parameters
let doc_comment = format!( let doc_comment = make_stream_doc_comment(method);
"{}returns a Stream<Item = {}> by making successive calls to {}",
method
.doc_comment
.as_ref()
.map(|s| format!("{}\n\n", s))
.unwrap_or_else(String::new),
item.name(),
method.operation_id,
);
quote! { quote! {
#[doc = #doc_comment] #[doc = #doc_comment]
@ -1256,6 +1259,89 @@ impl Generator {
} }
} }
fn make_doc_comment(method: &OperationMethod) -> String {
let mut buf = String::new();
if let Some(summary) = &method.summary {
buf.push_str(summary.trim_end_matches(['.', ',']));
buf.push_str("\n\n");
}
if let Some(description) = &method.description {
buf.push_str(description);
buf.push_str("\n\n");
}
buf.push_str(&format!(
"Sends a `{}` request to `{}`",
method.method.to_ascii_uppercase(),
method.path.to_string(),
));
if method
.params
.iter()
.filter(|param| param.description.is_some())
.count()
> 0
{
buf.push_str("\n\nArguments:\n");
for param in &method.params {
buf.push_str(&format!("- `{}`", param.name));
if let Some(description) = &param.description {
buf.push_str(": ");
buf.push_str(description);
}
buf.push('\n');
}
}
buf
}
fn make_stream_doc_comment(method: &OperationMethod) -> String {
let mut buf = String::new();
if let Some(summary) = &method.summary {
buf.push_str(summary.trim_end_matches(['.', ',']));
buf.push_str(" as a Stream\n\n");
}
if let Some(description) = &method.description {
buf.push_str(description);
buf.push_str("\n\n");
}
buf.push_str(&format!(
"Sends repeated `{}` requests to `{}` until there are no more results.",
method.method.to_ascii_uppercase(),
method.path.to_string(),
));
if method
.params
.iter()
.filter(|param| param.api_name.as_str() != "page_token")
.filter(|param| param.description.is_some())
.count()
> 0
{
buf.push_str("\n\nArguments:\n");
for param in &method.params {
if param.api_name.as_str() == "page_token" {
continue;
}
buf.push_str(&format!("- `{}`", param.name));
if let Some(description) = &param.description {
buf.push_str(": ");
buf.push_str(description);
}
buf.push('\n');
}
}
buf
}
fn last_two<T>(items: &[T]) -> (Option<&T>, Option<&T>) { fn last_two<T>(items: &[T]) -> (Option<&T>, Option<&T>) {
match items.len() { match items.len() {
0 => (None, None), 0 => (None, None),

View File

@ -162,7 +162,7 @@ impl Client {
&self.client &self.client
} }
#[doc = "control_hold: POST /v1/control/hold"] #[doc = "Sends a `POST` request to `/v1/control/hold`"]
pub async fn control_hold<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> { pub async fn control_hold<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> {
let url = format!("{}/v1/control/hold", self.baseurl,); let url = format!("{}/v1/control/hold", self.baseurl,);
let request = self.client.post(url).build()?; let request = self.client.post(url).build()?;
@ -174,7 +174,7 @@ impl Client {
} }
} }
#[doc = "control_resume: POST /v1/control/resume"] #[doc = "Sends a `POST` request to `/v1/control/resume`"]
pub async fn control_resume<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> { pub async fn control_resume<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> {
let url = format!("{}/v1/control/resume", self.baseurl,); let url = format!("{}/v1/control/resume", self.baseurl,);
let request = self.client.post(url).build()?; let request = self.client.post(url).build()?;
@ -186,7 +186,7 @@ impl Client {
} }
} }
#[doc = "task_get: GET /v1/task/{task}"] #[doc = "Sends a `GET` request to `/v1/task/{task}`"]
pub async fn task_get<'a>( pub async fn task_get<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -205,7 +205,7 @@ impl Client {
} }
} }
#[doc = "tasks_get: GET /v1/tasks"] #[doc = "Sends a `GET` request to `/v1/tasks`"]
pub async fn tasks_get<'a>(&'a self) -> Result<ResponseValue<Vec<types::Task>>, Error<()>> { pub async fn tasks_get<'a>(&'a self) -> Result<ResponseValue<Vec<types::Task>>, Error<()>> {
let url = format!("{}/v1/tasks", self.baseurl,); let url = format!("{}/v1/tasks", self.baseurl,);
let request = self.client.get(url).build()?; let request = self.client.get(url).build()?;
@ -217,7 +217,7 @@ impl Client {
} }
} }
#[doc = "task_submit: POST /v1/tasks"] #[doc = "Sends a `POST` request to `/v1/tasks`"]
pub async fn task_submit<'a>( pub async fn task_submit<'a>(
&'a self, &'a self,
body: &'a types::TaskSubmit, body: &'a types::TaskSubmit,
@ -232,7 +232,7 @@ impl Client {
} }
} }
#[doc = "task_events_get: GET /v1/tasks/{task}/events"] #[doc = "Sends a `GET` request to `/v1/tasks/{task}/events`"]
pub async fn task_events_get<'a>( pub async fn task_events_get<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -257,7 +257,7 @@ impl Client {
} }
} }
#[doc = "task_outputs_get: GET /v1/tasks/{task}/outputs"] #[doc = "Sends a `GET` request to `/v1/tasks/{task}/outputs`"]
pub async fn task_outputs_get<'a>( pub async fn task_outputs_get<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -276,7 +276,7 @@ impl Client {
} }
} }
#[doc = "task_output_download: GET /v1/tasks/{task}/outputs/{output}"] #[doc = "Sends a `GET` request to `/v1/tasks/{task}/outputs/{output}`"]
pub async fn task_output_download<'a>( pub async fn task_output_download<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -297,7 +297,7 @@ impl Client {
} }
} }
#[doc = "user_create: POST /v1/users"] #[doc = "Sends a `POST` request to `/v1/users`"]
pub async fn user_create<'a>( pub async fn user_create<'a>(
&'a self, &'a self,
body: &'a types::UserCreate, body: &'a types::UserCreate,
@ -312,7 +312,7 @@ impl Client {
} }
} }
#[doc = "whoami: GET /v1/whoami"] #[doc = "Sends a `GET` request to `/v1/whoami`"]
pub async fn whoami<'a>(&'a self) -> Result<ResponseValue<types::WhoamiResult>, Error<()>> { pub async fn whoami<'a>(&'a self) -> Result<ResponseValue<types::WhoamiResult>, Error<()>> {
let url = format!("{}/v1/whoami", self.baseurl,); let url = format!("{}/v1/whoami", self.baseurl,);
let request = self.client.get(url).build()?; let request = self.client.get(url).build()?;
@ -324,7 +324,7 @@ impl Client {
} }
} }
#[doc = "worker_bootstrap: POST /v1/worker/bootstrap"] #[doc = "Sends a `POST` request to `/v1/worker/bootstrap`"]
pub async fn worker_bootstrap<'a>( pub async fn worker_bootstrap<'a>(
&'a self, &'a self,
body: &'a types::WorkerBootstrap, body: &'a types::WorkerBootstrap,
@ -339,7 +339,7 @@ impl Client {
} }
} }
#[doc = "worker_ping: GET /v1/worker/ping"] #[doc = "Sends a `GET` request to `/v1/worker/ping`"]
pub async fn worker_ping<'a>( pub async fn worker_ping<'a>(
&'a self, &'a self,
) -> Result<ResponseValue<types::WorkerPingResult>, Error<()>> { ) -> Result<ResponseValue<types::WorkerPingResult>, Error<()>> {
@ -353,7 +353,7 @@ impl Client {
} }
} }
#[doc = "worker_task_append: POST /v1/worker/task/{task}/append"] #[doc = "Sends a `POST` request to `/v1/worker/task/{task}/append`"]
pub async fn worker_task_append<'a>( pub async fn worker_task_append<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -373,7 +373,7 @@ impl Client {
} }
} }
#[doc = "worker_task_upload_chunk: POST /v1/worker/task/{task}/chunk"] #[doc = "Sends a `POST` request to `/v1/worker/task/{task}/chunk`"]
pub async fn worker_task_upload_chunk<'a, B: Into<reqwest::Body>>( pub async fn worker_task_upload_chunk<'a, B: Into<reqwest::Body>>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -393,7 +393,7 @@ impl Client {
} }
} }
#[doc = "worker_task_complete: POST /v1/worker/task/{task}/complete"] #[doc = "Sends a `POST` request to `/v1/worker/task/{task}/complete`"]
pub async fn worker_task_complete<'a>( pub async fn worker_task_complete<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -413,7 +413,7 @@ impl Client {
} }
} }
#[doc = "worker_task_add_output: POST /v1/worker/task/{task}/output"] #[doc = "Sends a `POST` request to `/v1/worker/task/{task}/output`"]
pub async fn worker_task_add_output<'a>( pub async fn worker_task_add_output<'a>(
&'a self, &'a self,
task: &'a str, task: &'a str,
@ -433,7 +433,7 @@ impl Client {
} }
} }
#[doc = "workers_list: GET /v1/workers"] #[doc = "Sends a `GET` request to `/v1/workers`"]
pub async fn workers_list<'a>( pub async fn workers_list<'a>(
&'a self, &'a self,
) -> Result<ResponseValue<types::WorkersResult>, Error<()>> { ) -> Result<ResponseValue<types::WorkersResult>, Error<()>> {
@ -447,7 +447,7 @@ impl Client {
} }
} }
#[doc = "workers_recycle: POST /v1/workers/recycle"] #[doc = "Sends a `POST` request to `/v1/workers/recycle`"]
pub async fn workers_recycle<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> { pub async fn workers_recycle<'a>(&'a self) -> Result<ResponseValue<()>, Error<()>> {
let url = format!("{}/v1/workers/recycle", self.baseurl,); let url = format!("{}/v1/workers/recycle", self.baseurl,);
let request = self.client.post(url).build()?; let request = self.client.post(url).build()?;

View File

@ -103,7 +103,7 @@ impl Client {
&self.client &self.client
} }
#[doc = "enrol: POST /enrol"] #[doc = "Sends a `POST` request to `/enrol`"]
pub async fn enrol<'a>( pub async fn enrol<'a>(
&'a self, &'a self,
body: &'a types::EnrolBody, body: &'a types::EnrolBody,
@ -118,7 +118,7 @@ impl Client {
} }
} }
#[doc = "global_jobs: GET /global/jobs"] #[doc = "Sends a `GET` request to `/global/jobs`"]
pub async fn global_jobs<'a>( pub async fn global_jobs<'a>(
&'a self, &'a self,
) -> Result<ResponseValue<types::GlobalJobsResult>, Error<()>> { ) -> Result<ResponseValue<types::GlobalJobsResult>, Error<()>> {
@ -132,7 +132,7 @@ impl Client {
} }
} }
#[doc = "ping: GET /ping"] #[doc = "Sends a `GET` request to `/ping`"]
pub async fn ping<'a>(&'a self) -> Result<ResponseValue<types::PingResult>, Error<()>> { pub async fn ping<'a>(&'a self) -> Result<ResponseValue<types::PingResult>, Error<()>> {
let url = format!("{}/ping", self.baseurl,); let url = format!("{}/ping", self.baseurl,);
let request = self.client.get(url).build()?; let request = self.client.get(url).build()?;
@ -144,7 +144,7 @@ impl Client {
} }
} }
#[doc = "report_finish: POST /report/finish"] #[doc = "Sends a `POST` request to `/report/finish`"]
pub async fn report_finish<'a>( pub async fn report_finish<'a>(
&'a self, &'a self,
body: &'a types::ReportFinishBody, body: &'a types::ReportFinishBody,
@ -159,7 +159,7 @@ impl Client {
} }
} }
#[doc = "report_output: POST /report/output"] #[doc = "Sends a `POST` request to `/report/output`"]
pub async fn report_output<'a>( pub async fn report_output<'a>(
&'a self, &'a self,
body: &'a types::ReportOutputBody, body: &'a types::ReportOutputBody,
@ -174,7 +174,7 @@ impl Client {
} }
} }
#[doc = "report_start: POST /report/start"] #[doc = "Sends a `POST` request to `/report/start`"]
pub async fn report_start<'a>( pub async fn report_start<'a>(
&'a self, &'a self,
body: &'a types::ReportStartBody, body: &'a types::ReportStartBody,

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ impl Client {
&self.client &self.client
} }
#[doc = "freeform_response: GET "] #[doc = "Sends a `GET` request to ``"]
pub async fn freeform_response<'a>( pub async fn freeform_response<'a>(
&'a self, &'a self,
) -> Result<ResponseValue<ByteStream>, Error<ByteStream>> { ) -> Result<ResponseValue<ByteStream>, Error<ByteStream>> {

View File

@ -43,7 +43,7 @@ impl Client {
&self.client &self.client
} }
#[doc = "renamed_parameters: GET /{ref}/{type}/{trait}"] #[doc = "Sends a `GET` request to `/{ref}/{type}/{trait}`"]
pub async fn renamed_parameters<'a>( pub async fn renamed_parameters<'a>(
&'a self, &'a self,
ref_: &'a str, ref_: &'a str,

File diff suppressed because it is too large Load Diff