use async_trait::async_trait;
use axum::{
routing::{get, MethodRouter},
Router,
};
use std::sync::Arc;
#[tokio::main]
async fn main() {
let home_rc = Arc::new(Service::new());
let admin_rc = home_rc.clone();
App::new()
.server(Arc::new(GrpcServer::new()))
.server(Arc::new(
HttpServer::new()
.router(RouterData {
path: "/",
method: get(|| async move { home_rc.home_page().await }),
})
.router(RouterData {
path: "/admin",
method: get(|| async move { admin_rc.home_page().await }),
}),
))
.run();
tokio::select! {
_ = tokio::signal::ctrl_c() => {},
}
}
struct Service {
name: String,
}
impl Service {
fn new() -> Self {
Self {
name: "132132".to_string(),
}
}
}
impl Service {
async fn home_page(&mut self) -> String {
println!("-----123----");
format!("--Home Page--{}", self.name)
}
async fn admin_page(&mut self) -> String {
println!("-----456----");
format!("--Admin Page--{}", self.name)
}
}
struct App {
servers: Vec<Arc<dyn Server + Send + Sync>>,
}
impl App {
fn new() -> Self {
Self {
servers: Vec::new(),
}
}
fn server(mut self, srv: Arc<dyn Server + Send + Sync>) -> Self {
self.servers.push(srv);
self
}
fn run(&self) {
for srv in self.servers.iter() {
let srv_rc = srv.clone();
tokio::spawn(async move {
srv_rc.start().await;
});
}
}
}
struct RouterData {
path: &'static str,
method: MethodRouter,
}
#[async_trait]
pub trait Server {
async fn start(&self);
}
struct HttpServer {
router: Vec<RouterData>,
}
impl HttpServer {
fn new() -> Self {
Self { router: Vec::new() }
}
fn router(mut self, r: RouterData) -> Self {
self.router.push(r);
self
}
}
#[async_trait]
impl Server for HttpServer {
async fn start(&self) {
println!("-----http server------");
let mut app = Router::new();
for r in self.router.iter() {
app = app.route(r.path, r.method.clone());
}
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
}
struct GrpcServer;
impl GrpcServer {
fn new() -> Self {
Self
}
}
#[async_trait]
impl Server for GrpcServer {
async fn start(&self) {
println!("-----grpc server------");
}
}
How to call the home_page and admin_page methods of the Service structure in the router method of the HttpServer structure, home_rc.home_page().await and admin_rc.home_page().await, This call results in an error, as follows:
annot borrow data in an `Arc` as mutable
trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc<Service>`