scufflecloud_email/
services.rs

1use std::net::SocketAddr;
2use std::sync::Arc;
3
4use axum::Extension;
5use axum::http::StatusCode;
6use tower_http::trace::TraceLayer;
7
8use crate::EmailConfig;
9
10mod email;
11
12#[derive(Debug)]
13pub struct EmailSvc<G> {
14    _phantom: std::marker::PhantomData<G>,
15}
16
17impl<G> Default for EmailSvc<G> {
18    fn default() -> Self {
19        Self {
20            _phantom: std::marker::PhantomData,
21        }
22    }
23}
24
25impl<G: EmailConfig> scuffle_bootstrap::Service<G> for EmailSvc<G> {
26    async fn run(self, global: Arc<G>, ctx: scuffle_context::Context) -> anyhow::Result<()> {
27        // gRPC
28        let email_svc = pb::scufflecloud::email::v1::email_service_server::EmailServiceServer::new(EmailSvc::<G>::default());
29
30        let reflection_v1_svc = tonic_reflection::server::Builder::configure()
31            .register_encoded_file_descriptor_set(pb::ANNOTATIONS_PB)
32            .build_v1()?;
33        let reflection_v1alpha_svc = tonic_reflection::server::Builder::configure()
34            .register_encoded_file_descriptor_set(pb::ANNOTATIONS_PB)
35            .build_v1alpha()?;
36
37        let mut builder = tonic::service::Routes::builder();
38        builder.add_service(email_svc);
39        builder.add_service(reflection_v1_svc);
40        builder.add_service(reflection_v1alpha_svc);
41        let grpc_router = builder.routes().prepare().into_axum_router();
42
43        let router = axum::Router::new()
44            .merge(grpc_router)
45            .layer(TraceLayer::new_for_http())
46            .layer(Extension(Arc::clone(&global)))
47            .fallback(StatusCode::NOT_FOUND);
48
49        scuffle_http::HttpServer::builder()
50            .tower_make_service_with_addr(router.into_make_service_with_connect_info::<SocketAddr>())
51            .bind(global.bind())
52            .ctx(ctx)
53            .build()
54            .run()
55            .await?;
56
57        Ok(())
58    }
59}