Skip to main content

connectrpc_reflection/generated/connect/
grpc.reflection.v1.reflection.__connect.rs

1///Shorthand for `OwnedView<ServerReflectionRequestView<'static>>`.
2pub type OwnedServerReflectionRequestView = ::buffa::view::OwnedView<
3    crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionRequestView<
4        'static,
5    >,
6>;
7///Shorthand for `OwnedView<ServerReflectionResponseView<'static>>`.
8pub type OwnedServerReflectionResponseView = ::buffa::view::OwnedView<
9    crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionResponseView<
10        'static,
11    >,
12>;
13impl ::connectrpc::Encodable<
14    crate::proto::grpc::reflection::v1::ServerReflectionResponse,
15>
16for crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionResponseView<'_> {
17    fn encode(
18        &self,
19        codec: ::connectrpc::CodecFormat,
20    ) -> ::std::result::Result<::buffa::bytes::Bytes, ::connectrpc::ConnectError> {
21        ::connectrpc::__codegen::encode_view_body(self, codec)
22    }
23}
24impl ::connectrpc::Encodable<
25    crate::proto::grpc::reflection::v1::ServerReflectionResponse,
26>
27for ::buffa::view::OwnedView<
28    crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionResponseView<
29        'static,
30    >,
31> {
32    fn encode(
33        &self,
34        codec: ::connectrpc::CodecFormat,
35    ) -> ::std::result::Result<::buffa::bytes::Bytes, ::connectrpc::ConnectError> {
36        ::connectrpc::__codegen::encode_view_body(self.reborrow(), codec)
37    }
38    /// An `OwnedView` still holds the buffer it was decoded from, so
39    /// its large fields can be handed to the response body by
40    /// reference count instead of copied. The bare view impl above
41    /// cannot do this: it has borrows but no buffer to name.
42    fn encode_segments(
43        &self,
44        codec: ::connectrpc::CodecFormat,
45    ) -> ::std::result::Result<::connectrpc::EncodedBody, ::connectrpc::ConnectError> {
46        ::connectrpc::__codegen::encode_view_body_segments(
47            self.reborrow(),
48            self.bytes(),
49            codec,
50        )
51    }
52}
53/// Full service name for this service.
54pub const SERVER_REFLECTION_SERVICE_NAME: &str = "grpc.reflection.v1.ServerReflection";
55/// Static [`Spec`](::connectrpc::Spec) for the `ServerReflectionInfo` RPC, as seen by the server; the generated client passes it with [`origin`](::connectrpc::Spec::origin) `Client` (compare across sides with [`Spec::same_method`](::connectrpc::Spec::same_method)).
56pub const SERVER_REFLECTION_SERVER_REFLECTION_INFO_SPEC: ::connectrpc::Spec = ::connectrpc::Spec::server(
57        "/grpc.reflection.v1.ServerReflection/ServerReflectionInfo",
58        ::connectrpc::StreamType::BidiStream,
59    )
60    .with_idempotency_level(::connectrpc::IdempotencyLevel::Unknown);
61/// Server trait for ServerReflection.
62///
63/// # Implementing handlers
64///
65/// Implement methods with plain `async fn`; the returned future satisfies
66/// the `Send` bound automatically.
67///
68/// **Unary and server-streaming requests** arrive as
69/// [`ServiceRequest<'_, Req>`](::connectrpc::ServiceRequest): a zero-copy
70/// view of the request plus its body, valid for the duration of the call.
71/// Fields are read directly (`request.name` is a `&str` into the decoded
72/// buffer) and the borrow may be held across `.await` points. Anything
73/// that must outlive the call — `tokio::spawn`, channels, server state,
74/// or data captured by a returned response stream — takes owned data:
75/// call `request.to_owned_message()` (or copy the specific fields)
76/// first.
77///
78/// **Client-streaming and bidi requests** arrive as
79/// [`InboundStream<Req>`](::connectrpc::InboundStream) — a
80/// `ServiceStream` of [`StreamMessage`](::connectrpc::StreamMessage)s.
81/// Each item owns its decoded buffer and is `Send + 'static`, so items
82/// can be buffered or moved into spawned tasks; read fields zero-copy
83/// through the generated accessor methods (`item.name()`) or `.view()`,
84/// convert with `.to_owned_message()`, or yield an item back unchanged —
85/// `StreamMessage<M>` implements `Encodable<M>`.
86///
87/// Request types resolved through `extern_path` (e.g. well-known types
88/// from another crate) use the same wrappers; the crate that owns the
89/// type must be generated with buffa ≥ 0.9.0 and views enabled so the
90/// backing `HasMessageView` impl exists.
91///
92/// The `impl Encodable<Out>` return bound accepts the owned `Out`, the
93/// generated `OutView<'_>` / `OwnedOutView`,
94/// [`MaybeBorrowed`](::connectrpc::MaybeBorrowed), or
95/// [`PreEncoded`](::connectrpc::PreEncoded) for handlers that encode a
96/// non-`'static` view internally and pass the bytes across the handler
97/// boundary. View bodies are not emitted for output types mapped via
98/// `extern_path` (the impl would be an orphan); return owned for
99/// WKT/extern outputs.
100///
101/// Server-streaming and bidi-streaming methods return
102/// `ServiceStream<impl Encodable<Out> + Send + use<Self>>`. The
103/// `use<Self>` precise-capturing clause excludes `&self`'s lifetime and
104/// the request's lifetime (unary methods use `use<'a, Self>` and may
105/// borrow from `&self`), so stream items must be `'static` and cannot
106/// borrow from the request. To stream view-encoded data, encode each
107/// item inside the stream body and yield
108/// [`PreEncoded`](::connectrpc::PreEncoded) — see its `# Streaming
109/// example` doc.
110#[allow(clippy::type_complexity)]
111pub trait ServerReflection: Send + Sync + 'static {
112    /// The reflection service is structured as a bidirectional stream, ensuring
113    /// all related requests go to a single server.
114    ///
115    /// Each `requests` item is a [`StreamMessage`](::connectrpc::StreamMessage):
116    /// it owns its buffer, is `Send + 'static`, and exposes zero-copy
117    /// accessor methods (`item.name()`), `.view()`, and
118    /// `.to_owned_message()`.
119    fn server_reflection_info(
120        &self,
121        ctx: ::connectrpc::RequestContext,
122        requests: ::connectrpc::InboundStream<
123            crate::proto::grpc::reflection::v1::ServerReflectionRequest,
124        >,
125    ) -> impl ::std::future::Future<
126        Output = ::connectrpc::ServiceResult<
127            ::connectrpc::ServiceStream<
128                impl ::connectrpc::Encodable<
129                    crate::proto::grpc::reflection::v1::ServerReflectionResponse,
130                > + Send + use<Self>,
131            >,
132        >,
133    > + Send;
134}
135/// Extension trait for registering a service implementation with a Router.
136///
137/// This trait is automatically implemented for all types that implement the service trait.
138/// Prefer [`Router::add_service`](::connectrpc::Router::add_service) for
139/// top-down registration; `register` remains available for compatibility
140/// and cases where the service-first call shape is more convenient.
141///
142/// # Example
143///
144/// ```rust,ignore
145/// use std::sync::Arc;
146///
147/// let service = Arc::new(MyServiceImpl);
148/// let router = service.register(Router::new());
149/// ```
150pub trait ServerReflectionExt: ServerReflection {
151    /// Register this service implementation with a Router.
152    ///
153    /// Takes ownership of the `Arc<Self>` and returns a new Router with
154    /// this service's methods registered.
155    fn register(
156        self: ::std::sync::Arc<Self>,
157        router: ::connectrpc::Router,
158    ) -> ::connectrpc::Router;
159}
160impl<S: ServerReflection> ServerReflectionExt for S {
161    fn register(
162        self: ::std::sync::Arc<Self>,
163        router: ::connectrpc::Router,
164    ) -> ::connectrpc::Router {
165        router
166            .route_view_bidi_stream::<
167                _,
168                _,
169                crate::proto::grpc::reflection::v1::ServerReflectionResponse,
170            >(
171                SERVER_REFLECTION_SERVICE_NAME,
172                "ServerReflectionInfo",
173                ::connectrpc::view_bidi_streaming_handler_fn({
174                    let svc = ::std::sync::Arc::clone(&self);
175                    move |ctx, req| {
176                        let svc = ::std::sync::Arc::clone(&svc);
177                        async move {
178                            let req = ::connectrpc::dispatcher::codegen::into_stream_messages::<
179                                crate::proto::grpc::reflection::v1::ServerReflectionRequest,
180                            >(req);
181                            svc.server_reflection_info(ctx, req).await
182                        }
183                    }
184                }),
185            )
186            .with_spec(SERVER_REFLECTION_SERVER_REFLECTION_INFO_SPEC)
187    }
188}
189/// Type-inference marker used by [`Router::add_service`](::connectrpc::Router::add_service).
190#[doc(hidden)]
191pub struct ServerReflectionRegisterMarker;
192impl<S: ServerReflection> ::connectrpc::ServiceRegister<ServerReflectionRegisterMarker>
193for ::std::sync::Arc<S> {
194    fn register_service(self, router: ::connectrpc::Router) -> ::connectrpc::Router {
195        <S as ServerReflectionExt>::register(self, router)
196    }
197}
198/// Monomorphic dispatcher for `ServerReflection`.
199///
200/// Unlike `.register(Router)` which type-erases each method into an `Arc<dyn ErasedHandler>` stored in a `HashMap`, this struct dispatches via a compile-time `match` on method name: no vtable, no hash lookup.
201///
202/// # Example
203///
204/// ```rust,ignore
205/// use connectrpc::ConnectRpcService;
206///
207/// let server = ServerReflectionServer::new(MyImpl);
208/// let service = ConnectRpcService::new(server);
209/// // hand `service` to axum/hyper as a fallback_service
210/// ```
211pub struct ServerReflectionServer<T> {
212    inner: ::std::sync::Arc<T>,
213}
214impl<T: ServerReflection> ServerReflectionServer<T> {
215    /// Wrap a service implementation in a monomorphic dispatcher.
216    pub fn new(service: T) -> Self {
217        Self {
218            inner: ::std::sync::Arc::new(service),
219        }
220    }
221    /// Wrap an already-`Arc`'d service implementation.
222    pub fn from_arc(inner: ::std::sync::Arc<T>) -> Self {
223        Self { inner }
224    }
225}
226impl<T> Clone for ServerReflectionServer<T> {
227    fn clone(&self) -> Self {
228        Self {
229            inner: ::std::sync::Arc::clone(&self.inner),
230        }
231    }
232}
233impl<T: ServerReflection> ::connectrpc::Dispatcher for ServerReflectionServer<T> {
234    #[inline]
235    fn lookup(
236        &self,
237        path: &str,
238    ) -> Option<::connectrpc::dispatcher::codegen::MethodDescriptor> {
239        let method = path.strip_prefix("grpc.reflection.v1.ServerReflection/")?;
240        match method {
241            "ServerReflectionInfo" => {
242                Some(
243                    ::connectrpc::dispatcher::codegen::MethodDescriptor::bidi_streaming()
244                        .with_spec(SERVER_REFLECTION_SERVER_REFLECTION_INFO_SPEC),
245                )
246            }
247            _ => None,
248        }
249    }
250    fn call_unary(
251        &self,
252        path: &str,
253        ctx: ::connectrpc::RequestContext,
254        request: ::connectrpc::Payload,
255        format: ::connectrpc::CodecFormat,
256    ) -> ::connectrpc::dispatcher::codegen::UnaryResult {
257        let Some(method) = path.strip_prefix("grpc.reflection.v1.ServerReflection/")
258        else {
259            return ::connectrpc::dispatcher::codegen::unimplemented_unary(path);
260        };
261        let _ = (&ctx, &request, &format);
262        match method {
263            _ => ::connectrpc::dispatcher::codegen::unimplemented_unary(path),
264        }
265    }
266    fn call_server_streaming(
267        &self,
268        path: &str,
269        ctx: ::connectrpc::RequestContext,
270        request: ::buffa::bytes::Bytes,
271        format: ::connectrpc::CodecFormat,
272    ) -> ::connectrpc::dispatcher::codegen::StreamingResult {
273        let Some(method) = path.strip_prefix("grpc.reflection.v1.ServerReflection/")
274        else {
275            return ::connectrpc::dispatcher::codegen::unimplemented_streaming(path);
276        };
277        let _ = (&ctx, &request, &format);
278        match method {
279            _ => ::connectrpc::dispatcher::codegen::unimplemented_streaming(path),
280        }
281    }
282    fn call_client_streaming(
283        &self,
284        path: &str,
285        ctx: ::connectrpc::RequestContext,
286        requests: ::connectrpc::dispatcher::codegen::RequestStream,
287        format: ::connectrpc::CodecFormat,
288    ) -> ::connectrpc::dispatcher::codegen::UnaryResult {
289        let Some(method) = path.strip_prefix("grpc.reflection.v1.ServerReflection/")
290        else {
291            return ::connectrpc::dispatcher::codegen::unimplemented_unary(path);
292        };
293        let _ = (&ctx, &requests, &format);
294        match method {
295            _ => ::connectrpc::dispatcher::codegen::unimplemented_unary(path),
296        }
297    }
298    fn call_bidi_streaming(
299        &self,
300        path: &str,
301        ctx: ::connectrpc::RequestContext,
302        requests: ::connectrpc::dispatcher::codegen::RequestStream,
303        format: ::connectrpc::CodecFormat,
304    ) -> ::connectrpc::dispatcher::codegen::StreamingResult {
305        let Some(method) = path.strip_prefix("grpc.reflection.v1.ServerReflection/")
306        else {
307            return ::connectrpc::dispatcher::codegen::unimplemented_streaming(path);
308        };
309        let _ = (&ctx, &requests, &format);
310        match method {
311            "ServerReflectionInfo" => {
312                let svc = ::std::sync::Arc::clone(&self.inner);
313                Box::pin(async move {
314                    let req_stream = ::connectrpc::dispatcher::codegen::decode_message_request_stream::<
315                        crate::proto::grpc::reflection::v1::ServerReflectionRequest,
316                    >(requests, format, ctx.decode_options().clone());
317                    let resp = svc.server_reflection_info(ctx, req_stream).await?;
318                    Ok(
319                        resp
320                            .map_body(|s| ::connectrpc::dispatcher::codegen::encode_response_stream::<
321                                crate::proto::grpc::reflection::v1::ServerReflectionResponse,
322                                _,
323                                _,
324                            >(s, format)),
325                    )
326                })
327            }
328            _ => ::connectrpc::dispatcher::codegen::unimplemented_streaming(path),
329        }
330    }
331}
332/// Client for this service.
333///
334/// Generic over `T: ClientTransport`. For **gRPC** (HTTP/2), use
335/// `Http2Connection` — it has honest `poll_ready` and composes with
336/// `tower::balance` for multi-connection load balancing. For **Connect
337/// over HTTP/1.1** (or unknown protocol), use `HttpClient`.
338///
339/// # Example (gRPC / HTTP/2)
340///
341/// ```rust,ignore
342/// use connectrpc::client::{Http2Connection, ClientConfig};
343/// use connectrpc::Protocol;
344///
345/// let uri: http::Uri = "http://localhost:8080".parse()?;
346/// let conn = Http2Connection::connect_plaintext(uri.clone()).await?.shared(1024);
347/// let config = ClientConfig::new(uri).with_protocol(Protocol::Grpc);
348///
349/// let client = ServerReflectionClient::new(conn, config);
350/// let response = client.server_reflection_info(request).await?;
351/// ```
352///
353/// # Example (Connect / HTTP/1.1 or ALPN)
354///
355/// ```rust,ignore
356/// use connectrpc::client::{HttpClient, ClientConfig};
357///
358/// let http = HttpClient::plaintext();  // cleartext http:// only
359/// let config = ClientConfig::new("http://localhost:8080".parse()?);
360///
361/// let client = ServerReflectionClient::new(http, config);
362/// let response = client.server_reflection_info(request).await?;
363/// ```
364///
365/// # Working with the response
366///
367/// Unary calls return [`UnaryResponse<OwnedView<FooView>>`](::connectrpc::client::UnaryResponse).
368/// [`view()`](::connectrpc::client::UnaryResponse::view) borrows the response
369/// message, so field access is zero-copy:
370///
371/// ```rust,ignore
372/// let resp = client.server_reflection_info(request).await?;
373/// let name: &str = resp.view().name;  // borrow into the response buffer
374/// ```
375///
376/// If you need the owned struct (e.g. to store or pass by value), use
377/// [`into_owned()`](::connectrpc::client::UnaryResponse::into_owned):
378///
379/// ```rust,ignore
380/// let owned = client.server_reflection_info(request).await?.into_owned();
381/// ```
382///
383/// [`into_view()`](::connectrpc::client::UnaryResponse::into_view) keeps the
384/// zero-copy decoded body (an `OwnedView`) without copying; field access on it
385/// goes through `.reborrow()`. Streaming responses yield one
386/// [`StreamMessage`](::connectrpc::StreamMessage) per received message from
387/// `.message().await` — read fields zero-copy through the generated accessor
388/// methods (`msg.name()`) or `.view()`, or convert with `.to_owned_message()`.
389#[cfg(feature = "client")]
390#[derive(Clone)]
391pub struct ServerReflectionClient<T> {
392    transport: T,
393    config: ::connectrpc::client::ClientConfig,
394}
395#[cfg(feature = "client")]
396impl<T> ServerReflectionClient<T>
397where
398    T: ::connectrpc::client::ClientTransport,
399    <T::ResponseBody as ::connectrpc::http_body::Body>::Error: ::std::fmt::Display,
400{
401    /// Create a new client with the given transport and configuration.
402    pub fn new(transport: T, config: ::connectrpc::client::ClientConfig) -> Self {
403        Self { transport, config }
404    }
405    /// Get the client configuration.
406    pub fn config(&self) -> &::connectrpc::client::ClientConfig {
407        &self.config
408    }
409    /// Get a mutable reference to the client configuration.
410    pub fn config_mut(&mut self) -> &mut ::connectrpc::client::ClientConfig {
411        &mut self.config
412    }
413    /// Call the ServerReflectionInfo RPC. Sends a request to /grpc.reflection.v1.ServerReflection/ServerReflectionInfo.
414    pub async fn server_reflection_info(
415        &self,
416    ) -> Result<
417        ::connectrpc::client::BidiStream<
418            T::ResponseBody,
419            crate::proto::grpc::reflection::v1::ServerReflectionRequest,
420            crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionResponseView<
421                'static,
422            >,
423        >,
424        ::connectrpc::ConnectError,
425    > {
426        self.server_reflection_info_with_options(
427                ::connectrpc::client::CallOptions::default(),
428            )
429            .await
430    }
431    /// Call the ServerReflectionInfo RPC with explicit per-call options. Options override [`ClientConfig`](::connectrpc::client::ClientConfig) defaults.
432    pub async fn server_reflection_info_with_options(
433        &self,
434        options: ::connectrpc::client::CallOptions,
435    ) -> Result<
436        ::connectrpc::client::BidiStream<
437            T::ResponseBody,
438            crate::proto::grpc::reflection::v1::ServerReflectionRequest,
439            crate::proto::grpc::reflection::v1::__buffa::view::ServerReflectionResponseView<
440                'static,
441            >,
442        >,
443        ::connectrpc::ConnectError,
444    > {
445        ::connectrpc::client::call_bidi_stream(
446                &self.transport,
447                &self.config,
448                SERVER_REFLECTION_SERVER_REFLECTION_INFO_SPEC
449                    .with_origin(::connectrpc::SpecOrigin::Client),
450                options,
451            )
452            .await
453    }
454}