refactor: separate reflection generation (#20)

This commit is contained in:
Víctor Martínez 2026-01-22 15:42:33 +01:00 committed by GitHub
parent f75dc1b9a4
commit 8452a6786b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 80 additions and 39 deletions

30
Cargo.lock generated
View file

@ -330,12 +330,19 @@ name = "granc"
version = "0.2.4" version = "0.2.4"
dependencies = [ dependencies = [
"clap", "clap",
"granc_core", "granc_core 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json", "serde_json",
"tokio", "tokio",
"tonic", "tonic",
] ]
[[package]]
name = "granc-tools"
version = "0.0.0"
dependencies = [
"tonic-prost-build",
]
[[package]] [[package]]
name = "granc_core" name = "granc_core"
version = "0.2.4" version = "0.2.4"
@ -353,10 +360,29 @@ dependencies = [
"tokio-stream", "tokio-stream",
"tonic", "tonic",
"tonic-prost", "tonic-prost",
"tonic-prost-build",
"tonic-reflection", "tonic-reflection",
] ]
[[package]]
name = "granc_core"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b70761ae61e50a3da701f80dec0a5768e43420895922e233894865ce3969cea"
dependencies = [
"futures-util",
"http",
"http-body",
"prost",
"prost-reflect",
"prost-types",
"serde_json",
"thiserror",
"tokio",
"tokio-stream",
"tonic",
"tonic-prost",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.4.13" version = "0.4.13"

View file

@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["granc", "granc-core", "echo-service"] members = ["granc", "granc-core", "granc-tools", "echo-service"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]

View file

@ -13,18 +13,10 @@ repository = { workspace = true }
rust-version = { workspace = true } rust-version = { workspace = true }
version = { workspace = true } version = { workspace = true }
[features]
gen-proto = ["dep:tonic-prost-build"]
[lib] [lib]
name = "granc_core" name = "granc_core"
path = "src/lib.rs" path = "src/lib.rs"
[[bin]]
name = "generate-reflection-service"
path = "bin/generate_reflection_service.rs"
required-features = ["gen-proto"]
[dependencies] [dependencies]
futures-util = "0.3.31" futures-util = "0.3.31"
http = "1.4.0" http = "1.4.0"
@ -38,7 +30,6 @@ tokio = { workspace = true, features = ["sync"] }
tokio-stream = "0.1.18" tokio-stream = "0.1.18"
tonic = { workspace = true } tonic = { workspace = true }
tonic-prost = { workspace = true } tonic-prost = { workspace = true }
tonic-prost-build = { workspace = true, optional = true }
[dev-dependencies] [dev-dependencies]
echo-service = { path = "../echo-service" } echo-service = { path = "../echo-service" }

View file

@ -7,11 +7,10 @@ pub struct ServerReflectionRequest {
/// To use reflection service, the client should set one of the following /// To use reflection service, the client should set one of the following
/// fields in message_request. The server distinguishes requests by their /// fields in message_request. The server distinguishes requests by their
/// defined field and then handles them using corresponding methods. /// defined field and then handles them using corresponding methods.
#[prost( #[prost(oneof = "server_reflection_request::MessageRequest", tags = "3, 4, 5, 6, 7")]
oneof = "server_reflection_request::MessageRequest", pub message_request: ::core::option::Option<
tags = "3, 4, 5, 6, 7" server_reflection_request::MessageRequest,
)] >,
pub message_request: ::core::option::Option<server_reflection_request::MessageRequest>,
} }
/// Nested message and enum types in `ServerReflectionRequest`. /// Nested message and enum types in `ServerReflectionRequest`.
pub mod server_reflection_request { pub mod server_reflection_request {
@ -67,11 +66,10 @@ pub struct ServerReflectionResponse {
pub original_request: ::core::option::Option<ServerReflectionRequest>, pub original_request: ::core::option::Option<ServerReflectionRequest>,
/// The server sets one of the following fields according to the message_request /// The server sets one of the following fields according to the message_request
/// in the request. /// in the request.
#[prost( #[prost(oneof = "server_reflection_response::MessageResponse", tags = "4, 5, 6, 7")]
oneof = "server_reflection_response::MessageResponse", pub message_response: ::core::option::Option<
tags = "4, 5, 6, 7" server_reflection_response::MessageResponse,
)] >,
pub message_response: ::core::option::Option<server_reflection_response::MessageResponse>,
} }
/// Nested message and enum types in `ServerReflectionResponse`. /// Nested message and enum types in `ServerReflectionResponse`.
pub mod server_reflection_response { pub mod server_reflection_response {
@ -153,10 +151,10 @@ pub mod server_reflection_client {
dead_code, dead_code,
missing_docs, missing_docs,
clippy::wildcard_imports, clippy::wildcard_imports,
clippy::let_unit_value clippy::let_unit_value,
)] )]
use tonic::codegen::http::Uri;
use tonic::codegen::*; use tonic::codegen::*;
use tonic::codegen::http::Uri;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ServerReflectionClient<T> { pub struct ServerReflectionClient<T> {
inner: tonic::client::Grpc<T>, inner: tonic::client::Grpc<T>,
@ -195,13 +193,14 @@ pub mod server_reflection_client {
F: tonic::service::Interceptor, F: tonic::service::Interceptor,
T::ResponseBody: Default, T::ResponseBody: Default,
T: tonic::codegen::Service< T: tonic::codegen::Service<
http::Request<tonic::body::Body>, http::Request<tonic::body::Body>,
Response = http::Response< Response = http::Response<
<T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody, <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
>,
>, >,
<T as tonic::codegen::Service<http::Request<tonic::body::Body>>>::Error: >,
Into<StdError> + std::marker::Send + std::marker::Sync, <T as tonic::codegen::Service<
http::Request<tonic::body::Body>,
>>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
{ {
ServerReflectionClient::new(InterceptedService::new(inner, interceptor)) ServerReflectionClient::new(InterceptedService::new(inner, interceptor))
} }
@ -240,23 +239,33 @@ pub mod server_reflection_client {
/// all related requests go to a single server. /// all related requests go to a single server.
pub async fn server_reflection_info( pub async fn server_reflection_info(
&mut self, &mut self,
request: impl tonic::IntoStreamingRequest<Message = super::ServerReflectionRequest>, request: impl tonic::IntoStreamingRequest<
Message = super::ServerReflectionRequest,
>,
) -> std::result::Result< ) -> std::result::Result<
tonic::Response<tonic::codec::Streaming<super::ServerReflectionResponse>>, tonic::Response<tonic::codec::Streaming<super::ServerReflectionResponse>>,
tonic::Status, tonic::Status,
> { > {
self.inner.ready().await.map_err(|e| { self.inner
tonic::Status::unknown(format!("Service was not ready: {}", e.into())) .ready()
})?; .await
.map_err(|e| {
tonic::Status::unknown(
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic_prost::ProstCodec::default(); let codec = tonic_prost::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static( let path = http::uri::PathAndQuery::from_static(
"/grpc.reflection.v1.ServerReflection/ServerReflectionInfo", "/grpc.reflection.v1.ServerReflection/ServerReflectionInfo",
); );
let mut req = request.into_streaming_request(); let mut req = request.into_streaming_request();
req.extensions_mut().insert(GrpcMethod::new( req.extensions_mut()
"grpc.reflection.v1.ServerReflection", .insert(
"ServerReflectionInfo", GrpcMethod::new(
)); "grpc.reflection.v1.ServerReflection",
"ServerReflectionInfo",
),
);
self.inner.streaming(req, path, codec).await self.inner.streaming(req, path, codec).await
} }
} }

15
granc-tools/Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "granc-tools"
edition = { workspace = true }
publish = false
[features]
gen-proto = ["dep:tonic-prost-build"]
[[bin]]
name = "generate-reflection-service"
path = "bin/generate_reflection_service.rs"
required-features = ["gen-proto"]
[dependencies]
tonic-prost-build = { workspace = true, optional = true }

View file

@ -6,7 +6,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Generating Reflection Service types..."); println!("Generating Reflection Service types...");
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let out_dir = manifest_dir.join("src/reflection/generated"); let out_dir = manifest_dir.join("../granc-core/src/reflection/generated");
let proto_file = manifest_dir.join("proto/reflection.proto"); let proto_file = manifest_dir.join("proto/reflection.proto");
let proto_folder = manifest_dir.join("proto"); let proto_folder = manifest_dir.join("proto");