rsketch_server/grpc/
hello.rs

1// Copyright 2025 Crrow
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}