daoyi_cloud_common/
lib.rs

1pub use anyhow;
2pub use askama;
3pub use dotenvy;
4pub use rust_embed;
5pub use salvo;
6pub use salvo::catcher::Catcher;
7pub use salvo::conn::rustls::{Keycert, RustlsConfig};
8pub use salvo::prelude::*;
9pub use salvo::server::ServerHandle;
10pub use serde::Serialize;
11pub use tokio;
12pub use tokio::signal;
13pub use tracing::info;
14pub use serde_json;
15pub use cookie;
16
17pub mod common_hoops;
18pub mod common_test_routers_example;
19pub mod config;
20pub mod db;
21pub mod models;
22pub mod utils;
23
24pub use models::common_result::CommonResult;
25
26pub mod error;
27
28pub use error::AppError;
29pub mod redis;
30pub use redis::RedisClient;
31
32pub type AppResult<T> = Result<T, AppError>;
33pub type JsonResult<T> = Result<Json<T>, AppError>;
34pub type EmptyResult = Result<Json<Empty>, AppError>;
35
36pub fn json_ok<T>(data: T) -> JsonResult<T> {
37    Ok(Json(data))
38}
39#[derive(Serialize, ToSchema, Clone, Copy, Debug)]
40pub struct Empty {}
41pub fn empty_ok() -> JsonResult<Empty> {
42    Ok(Json(Empty {}))
43}
44
45pub async fn shutdown_signal(handle: ServerHandle) {
46    let ctrl_c = async {
47        signal::ctrl_c()
48            .await
49            .expect("failed to install Ctrl+C handler");
50    };
51
52    #[cfg(unix)]
53    let terminate = async {
54        signal::unix::signal(signal::unix::SignalKind::terminate())
55            .expect("failed to install signal handler")
56            .recv()
57            .await;
58    };
59
60    #[cfg(not(unix))]
61    let terminate = std::future::pending::<()>();
62
63    tokio::select! {
64        _ = ctrl_c => info!("ctrl_c signal received"),
65        _ = terminate => info!("terminate signal received"),
66    }
67    handle.stop_graceful(std::time::Duration::from_secs(60));
68}
69
70#[cfg(test)]
71mod tests {
72    use config::{Env, Format, Toml};
73    use salvo::prelude::*;
74    use salvo::test::{ResponseExt, TestClient};
75
76    use crate::config;
77
78    #[tokio::test]
79    async fn test_hello_world() {
80        let profile = Env::var("APP_PROFILE").unwrap_or_else(|| "test".to_string());
81        let data = Toml::file(
82            Env::var("APP_CONFIG")
83                .as_deref()
84                .unwrap_or(format!("config-{}.toml", profile).as_str()),
85        );
86        config::common_init(Some(data));
87
88        let service = Service::new(crate::common_test_routers_example::root());
89
90        let content = TestClient::get(format!(
91            "http://{}",
92            config::get().listen_addr.replace("0.0.0.0", "127.0.0.1")
93        ))
94        .send(&service)
95        .await
96        .take_string()
97        .await
98        .unwrap();
99        assert_eq!(content, "Hello World from salvo");
100    }
101}