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}