diff --git a/Cargo.lock b/Cargo.lock index e641364be..30cc7b73c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,6 +202,7 @@ dependencies = [ "anki_io", "anyhow", "inflections", + "itertools", "num_enum", "prost", "prost-build", diff --git a/rslib/proto/Cargo.toml b/rslib/proto/Cargo.toml index 2c01f6188..c3fdafb31 100644 --- a/rslib/proto/Cargo.toml +++ b/rslib/proto/Cargo.toml @@ -13,6 +13,7 @@ rust-version.workspace = true anki_io = { version = "0.0.0", path = "../io" } anyhow = "1.0.71" inflections = "1.1.1" +itertools = "0.10.5" prost-build = "0.11.9" prost-reflect = "0.11.4" prost-types = "0.11.9" diff --git a/rslib/proto/python.rs b/rslib/proto/python.rs index b735c1915..1f7f6f357 100644 --- a/rslib/proto/python.rs +++ b/rslib/proto/python.rs @@ -16,6 +16,8 @@ use prost_reflect::MessageDescriptor; use prost_reflect::MethodDescriptor; use prost_reflect::ServiceDescriptor; +use crate::utils::Comments; + pub(crate) fn write_python_interface(pool: &DescriptorPool) -> Result<()> { let output_path = Path::new("../../out/pylib/anki/_backend_generated.py"); create_dir_all(output_path.parent().unwrap())?; @@ -26,8 +28,9 @@ pub(crate) fn write_python_interface(pool: &DescriptorPool) -> Result<()> { if service.name() == "AnkidroidService" { continue; } + let comments = Comments::from_file(service.parent_file().file_descriptor_proto()); for method in service.methods() { - render_method(&service, &method, &mut out); + render_method(&service, &method, &comments, &mut out); } } @@ -45,18 +48,24 @@ pub(crate) fn write_python_interface(pool: &DescriptorPool) -> Result<()> { /// output = anki.generic_pb2.StringList() /// output.ParseFromString(raw_bytes) /// return output.vals -fn render_method(service: &ServiceDescriptor, method: &MethodDescriptor, out: &mut impl Write) { +fn render_method( + service: &ServiceDescriptor, + method: &MethodDescriptor, + comments: &Comments, + out: &mut impl Write, +) { let method_name = method.name().to_snake_case(); let input = method.input(); let output = method.output(); let service_idx = service.index(); let method_idx = method.index(); + let comments = format_comments(comments.get_for_path(method.path())); // raw bytes write!( out, r#" def {method_name}_raw(self, message: bytes) -> bytes: - return self._run_command({service_idx}, {method_idx}, message) + {comments}return self._run_command({service_idx}, {method_idx}, message) "# ) @@ -69,7 +78,7 @@ fn render_method(service: &ServiceDescriptor, method: &MethodDescriptor, out: &m write!( out, r#" def {method_name}({input_params}) -> {output_type}: - {input_assign} + {comments}{input_assign} raw_bytes = self._run_command({service_idx}, {method_idx}, message.SerializeToString()) output = {output_constructor}() output.ParseFromString(raw_bytes) @@ -80,6 +89,18 @@ fn render_method(service: &ServiceDescriptor, method: &MethodDescriptor, out: &m .unwrap(); } +fn format_comments(comments: Option<&str>) -> String { + comments + .as_ref() + .map(|c| { + format!( + r#""""{c}""" + "# + ) + }) + .unwrap_or_default() +} + /// If any of the following apply to the input type: /// - it has a single field /// - its name ends in Request diff --git a/rslib/proto/rust.rs b/rslib/proto/rust.rs index 03d8a0f15..8c36172a0 100644 --- a/rslib/proto/rust.rs +++ b/rslib/proto/rust.rs @@ -11,6 +11,7 @@ use anki_io::read_file; use anki_io::write_file_if_changed; use anyhow::Context; use anyhow::Result; +use itertools::Itertools; use prost_build::ServiceGenerator; use prost_reflect::DescriptorPool; @@ -151,12 +152,20 @@ pub trait Service { ); for method in &service.methods { + let comments = method + .comments + .leading + .iter() + .map(|c| format!(" /// {c}")) + .join("\n"); write!( buf, concat!( - " fn {method_name}(&self, input: super::{input_type}) -> ", + "{comments}\n", + "fn {method_name}(&self, input: super::{input_type}) -> ", "Result;\n" ), + comments = comments, method_name = method.name, input_type = method.input_type, output_type = method.output_type diff --git a/rslib/proto/utils.rs b/rslib/proto/utils.rs index 91c622c70..9dca9ec8d 100644 --- a/rslib/proto/utils.rs +++ b/rslib/proto/utils.rs @@ -19,16 +19,7 @@ impl Comments { .unwrap() .location .iter() - .map(|l| { - ( - l.path.clone(), - format!( - "{}{}", - l.leading_detached_comments.join("\n").trim(), - l.leading_comments().trim() - ), - ) - }) + .map(|l| (l.path.clone(), l.leading_comments().trim().to_string())) .collect(), } }