Skip to main content

snix_build/proto/
grpc_buildservice_wrapper.rs

1use crate::{buildservice::BuildService, proto};
2use futures::StreamExt;
3use futures::stream::BoxStream;
4use tonic::{Response, async_trait};
5
6/// Implements the gRPC server trait ([crate::proto::build_service_server::BuildService]
7/// for anything implementing [BuildService].
8pub struct GRPCBuildServiceWrapper<BUILD> {
9    inner: BUILD,
10}
11
12impl<BUILD> GRPCBuildServiceWrapper<BUILD> {
13    pub fn new(build_service: BUILD) -> Self {
14        Self {
15            inner: build_service,
16        }
17    }
18}
19
20#[async_trait]
21impl<BUILD> crate::proto::build_service_server::BuildService for GRPCBuildServiceWrapper<BUILD>
22where
23    BUILD: BuildService + Clone + 'static,
24{
25    type DoBuildStream = BoxStream<'static, tonic::Result<proto::BuildUpdate>>;
26
27    async fn do_build(
28        &self,
29        request: tonic::Request<proto::BuildRequest>,
30    ) -> tonic::Result<Response<Self::DoBuildStream>> {
31        let proto_build_request = request.into_inner();
32        let build_request = crate::buildservice::BuildRequest::try_from(proto_build_request)
33            .map_err(|err| tonic::Status::new(tonic::Code::InvalidArgument, err.to_string()))?;
34
35        let build_service = self.inner.clone();
36        let stream = async_stream::try_stream! {
37            let mut build_updates = build_service.do_build(build_request);
38            while let Some(build_update) = build_updates.next().await {
39                yield proto::BuildUpdate::from(build_update);
40            }
41        };
42
43        Ok(Response::new(stream.boxed()))
44    }
45}