pub mod cache;
#[cfg(feature = "cli")]
pub mod cli;
pub mod config;
pub mod constant;
pub mod controller;
pub mod entity;
pub mod eps;
pub mod error;
pub mod event;
pub mod middleware;
pub mod module;
pub mod service;
pub mod tag;
pub mod util;
pub mod prelude {
#![allow(ambiguous_glob_reexports)]
pub use crate::cache::{CacheFactory, CacheStore, MemoryCache, RedisCache};
pub use crate::config::*;
pub use crate::constant::*;
pub use crate::controller::{BaseController, ControllerOption, CrudApi};
pub use crate::entity::*;
pub use crate::error::{CoolError, CoolResponse, CoolResult, PageResult, Pagination};
pub use crate::event::{global_event_manager, EventManager};
pub use crate::middleware::{
authority, exception_filter, request_log, AdminInfo, AppUserInfo, AuthorityConfig,
DepotAppUserExt, DepotExt, ExceptionFilter, JwtClaims,
};
pub use crate::module::{global_module_registry, Module, ModuleInfo, ModuleRegistry};
pub use crate::service::{BaseService, ModifyType, SimpleService};
pub use crate::eps::{
global_eps_registry, ColumnInfo as EpsColumnInfo, ControllerEps, EpsRegistry, EpsScope,
ModuleInfo as EpsModuleInfo, QueryOpInfo as EpsQueryOpInfo, RouteInfo as EpsRouteInfo,
};
pub use crate::tag::{global_url_tag_store, TagType, UrlTagStore};
pub use crate::util;
#[cfg(feature = "cli")]
pub use crate::cli::{check, clear_entities_file, generate_entities_file};
pub use async_trait::async_trait;
pub use salvo::prelude::*;
pub use sea_orm::{
entity::prelude::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, DatabaseConnection,
EntityTrait, IntoActiveModel, ModelTrait, PaginatorTrait, QueryFilter, QueryOrder,
QuerySelect,
};
pub use serde::{Deserialize, Serialize};
pub use serde_json::{json, Value};
pub use validator::Validate;
}
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn init_logger() {
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
tracing_subscriber::registry()
.with(fmt::layer())
.with(EnvFilter::from_default_env().add_directive("cool_core=info".parse().unwrap()))
.init();
}
pub struct CoolApp {
pub config: config::CoolConfig,
pub db: Option<sea_orm::DatabaseConnection>,
pub modules: module::ModuleRegistry,
pub events: event::EventManager,
}
impl CoolApp {
pub fn new(config: config::CoolConfig) -> Self {
Self {
config,
db: None,
modules: module::ModuleRegistry::new(),
events: event::EventManager::new(),
}
}
pub fn database(mut self, db: sea_orm::DatabaseConnection) -> Self {
self.db = Some(db);
self
}
pub fn register<M: module::Module + 'static>(self, module: M) -> Self {
self.modules.register(module);
self
}
pub fn build_router(&self, prefix: &str) -> salvo::Router {
self.modules.build_router(prefix)
}
pub async fn run(self, addr: impl Into<String>) -> std::io::Result<()> {
use salvo::prelude::*;
let addr = addr.into();
if let Err(e) = self.modules.init_all() {
tracing::error!("模块初始化失败: {}", e);
return Err(std::io::Error::other(e));
}
let router = self.build_router("/");
let doc = OpenApi::new("openapi", "0.0.1").merge_router(&router);
let router = router
.unshift(doc.into_router("/api-doc/openapi.json"))
.unshift(SwaggerUi::new("/api-doc/openapi.json").into_router("/swagger-ui"));
let listener = TcpListener::new(addr.clone()).bind().await;
tracing::info!("🚀 服务已启动: http://{}", addr);
self.events
.emit(
event::events::SERVER_READY,
event::ServerReadyEvent {
address: addr.to_string(),
port: 0,
},
)
.await;
Server::new(listener).serve(router).await;
Ok(())
}
}
impl Default for CoolApp {
fn default() -> Self {
Self::new(config::CoolConfig::default())
}
}