More documentation generation (#12)
* generate rustdoc comments from .proto file comments * move imports to top of file * more docs gen * trait docs * more docs * use singular doc gen fn here * remove pesky space
This commit is contained in:
committed by
Lucio Franco
parent
d2355ed83c
commit
8becd257bc
@@ -1,4 +1,4 @@
|
||||
use crate::generate_doc_comments;
|
||||
use crate::{generate_doc_comment, generate_doc_comments};
|
||||
use proc_macro2::TokenStream;
|
||||
use prost_build::{Method, Service};
|
||||
use quote::{format_ident, quote};
|
||||
@@ -30,6 +30,7 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
/// Check if the service is ready.
|
||||
pub async fn ready(&mut self) -> Result<(), tonic::Status> {
|
||||
self.inner.ready().await.map_err(|e| {
|
||||
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
|
||||
@@ -51,8 +52,19 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream {
|
||||
|
||||
#[cfg(feature = "transport")]
|
||||
fn generate_connect(service_ident: &syn::Ident) -> TokenStream {
|
||||
let doc_example = format!(
|
||||
"let client = {}::connect(\"http://[::1]:50051\")?;",
|
||||
service_ident
|
||||
);
|
||||
let doc_example = generate_doc_comment(&doc_example);
|
||||
|
||||
quote! {
|
||||
impl #service_ident<tonic::transport::Channel> {
|
||||
/// Attempt to create a new client by connecting to a given endpoint.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
#doc_example
|
||||
/// ```
|
||||
pub fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
|
||||
where
|
||||
D: std::convert::TryInto<tonic::transport::Endpoint>,
|
||||
|
||||
@@ -171,6 +171,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
|
||||
let clients = &self.clients;
|
||||
|
||||
let client_service = quote::quote! {
|
||||
/// Generated client implementations.
|
||||
pub mod client {
|
||||
#![allow(unused_variables, dead_code, missing_docs)]
|
||||
use tonic::codegen::*;
|
||||
@@ -187,6 +188,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
|
||||
let servers = &self.servers;
|
||||
|
||||
let server_service = quote::quote! {
|
||||
/// Generated server implementations.
|
||||
pub mod server {
|
||||
#![allow(unused_variables, dead_code, missing_docs)]
|
||||
use tonic::codegen::*;
|
||||
@@ -202,7 +204,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
|
||||
}
|
||||
|
||||
// Generate a singular line of a doc comment
|
||||
fn generate_doc_comment(comment: &str, stream: &mut TokenStream) {
|
||||
fn generate_doc_comment(comment: &str) -> TokenStream {
|
||||
let mut doc_stream = TokenStream::new();
|
||||
|
||||
doc_stream.append(Ident::new("doc", Span::call_site()));
|
||||
@@ -211,8 +213,10 @@ fn generate_doc_comment(comment: &str, stream: &mut TokenStream) {
|
||||
|
||||
let group = Group::new(Delimiter::Bracket, doc_stream);
|
||||
|
||||
let mut stream = TokenStream::new();
|
||||
stream.append(Punct::new('#', Spacing::Alone));
|
||||
stream.append(group);
|
||||
stream
|
||||
}
|
||||
|
||||
// Generate a larger doc comment composed of many lines of doc comments
|
||||
@@ -220,7 +224,7 @@ fn generate_doc_comments<T: AsRef<str>>(comments: &[T]) -> TokenStream {
|
||||
let mut stream = TokenStream::new();
|
||||
|
||||
for comment in comments {
|
||||
generate_doc_comment(comment.as_ref(), &mut stream);
|
||||
stream.extend(generate_doc_comment(comment.as_ref()));
|
||||
}
|
||||
|
||||
stream
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::generate_doc_comments;
|
||||
use crate::{generate_doc_comment, generate_doc_comments};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use prost_build::{Method, Service};
|
||||
use quote::quote;
|
||||
@@ -12,6 +12,10 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream {
|
||||
let server_trait = quote::format_ident!("{}", service.name);
|
||||
let generated_trait = generate_trait(service, proto_path, server_trait.clone());
|
||||
let service_doc = generate_doc_comments(&service.comments.leading);
|
||||
let server_new_doc = generate_doc_comment(&format!(
|
||||
"Create a new {} from a type that implements {}.",
|
||||
server_make_service, server_trait
|
||||
));
|
||||
|
||||
quote! {
|
||||
#generated_trait
|
||||
@@ -29,6 +33,7 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream {
|
||||
}
|
||||
|
||||
impl<T: #server_trait> #server_make_service<T> {
|
||||
#server_new_doc
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = Arc::new(inner);
|
||||
Self::from_shared(inner)
|
||||
@@ -84,8 +89,13 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream {
|
||||
|
||||
fn generate_trait(service: &Service, proto_path: &str, server_trait: Ident) -> TokenStream {
|
||||
let methods = generate_trait_methods(service, proto_path);
|
||||
let trait_doc = generate_doc_comment(&format!(
|
||||
"Generated trait containing gRPC methods that should be implemented for use with {}Server.",
|
||||
service.name
|
||||
));
|
||||
|
||||
quote! {
|
||||
#trait_doc
|
||||
#[async_trait]
|
||||
pub trait #server_trait : Send + Sync + 'static {
|
||||
#methods
|
||||
@@ -103,35 +113,51 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream {
|
||||
let res_message: Path =
|
||||
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||
|
||||
let method_doc = generate_doc_comments(&method.comments.leading);
|
||||
|
||||
let method = match (method.client_streaming, method.server_streaming) {
|
||||
(false, false) => {
|
||||
quote! {
|
||||
#method_doc
|
||||
async fn #name(&self, request: tonic::Request<#req_message>)
|
||||
-> Result<tonic::Response<#res_message>, tonic::Status>;
|
||||
}
|
||||
}
|
||||
(true, false) => {
|
||||
quote! {
|
||||
#method_doc
|
||||
async fn #name(&self, request: tonic::Request<tonic::Streaming<#req_message>>)
|
||||
-> Result<tonic::Response<#res_message>, tonic::Status>;
|
||||
}
|
||||
}
|
||||
(false, true) => {
|
||||
let stream = quote::format_ident!("{}Stream", method.proto_name);
|
||||
let stream_doc = generate_doc_comment(&format!(
|
||||
"Server streaming response type for the {} method.",
|
||||
method.proto_name
|
||||
));
|
||||
|
||||
quote! {
|
||||
#stream_doc
|
||||
type #stream: Stream<Item = Result<#res_message, tonic::Status>> + Send + 'static;
|
||||
|
||||
#method_doc
|
||||
async fn #name(&self, request: tonic::Request<#req_message>)
|
||||
-> Result<tonic::Response<Self::#stream>, tonic::Status>;
|
||||
}
|
||||
}
|
||||
(true, true) => {
|
||||
let stream = quote::format_ident!("{}Stream", method.proto_name);
|
||||
let stream_doc = generate_doc_comment(&format!(
|
||||
"Server streaming response type for the {} method.",
|
||||
method.proto_name
|
||||
));
|
||||
|
||||
quote! {
|
||||
#stream_doc
|
||||
type #stream: Stream<Item = Result<#res_message, tonic::Status>> + Send + 'static;
|
||||
|
||||
#method_doc
|
||||
async fn #name(&self, request: tonic::Request<tonic::Streaming<#req_message>>)
|
||||
-> Result<tonic::Response<Self::#stream>, tonic::Status>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user