rsketch_server/grpc/
hello.rs1use std::sync::Arc;
16
17use async_trait::async_trait;
18use rsketch_api::pb::hello::v1::{HelloRequest, HelloResponse, hello_service_server};
19use tokio_util::sync::CancellationToken;
20use tonic::service::RoutesBuilder;
21use tonic_health::server::HealthReporter;
22
23use crate::{
24 error::{ApiError, ApiResult},
25 grpc::GrpcServiceHandler,
26};
27
28#[derive(Default)]
29pub struct HelloService;
30
31#[async_trait]
32impl hello_service_server::HelloService for HelloService {
33 async fn hello(
34 &self,
35 request: tonic::Request<HelloRequest>,
36 ) -> std::result::Result<tonic::Response<HelloResponse>, tonic::Status> {
37 let response = Self::hello_inner(request).map_err(tonic::Status::from)?;
38 Ok(response)
39 }
40}
41
42impl HelloService {
43 fn hello_inner(
44 request: tonic::Request<HelloRequest>,
45 ) -> ApiResult<tonic::Response<HelloResponse>> {
46 let name = request.into_inner().name;
47 if name.trim().is_empty() {
48 return Err(ApiError::InvalidArgument {
49 reason: "name must not be empty".to_string(),
50 });
51 }
52 let message = format!("Hello, {name}!");
53 Ok(tonic::Response::new(HelloResponse { message }))
54 }
55}
56
57#[async_trait]
58impl GrpcServiceHandler for HelloService {
59 fn service_name(&self) -> &'static str { "HelloService" }
60
61 fn file_descriptor_set(&self) -> &'static [u8] { rsketch_api::pb::GRPC_DESC }
62
63 fn register_service(self: &Arc<Self>, builder: &mut RoutesBuilder) {
64 builder.add_service(hello_service_server::HelloServiceServer::from_arc(
65 self.clone(),
66 ));
67 }
68
69 async fn readiness_reporting(
70 self: &Arc<Self>,
71 _cancellation_token: CancellationToken,
72 reporter: HealthReporter,
73 ) {
74 reporter
75 .set_serving::<hello_service_server::HelloServiceServer<Self>>()
76 .await;
77 }
78}