1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! # Kalgan - A Rust Framework for Web Developers
//!
//! Welcome to Kalgan API documentation.
//!
//! Please, see the [Official Site](https://www.markdownguide.org) for features and getting started.
#[macro_use]
extern crate lazy_static;

pub mod handler {
    mod asset;
    pub(crate) mod controller;
    mod error;
    pub mod middleware;
    pub(crate) mod resolver;
}
pub mod http {
    pub mod request;
    pub mod response;
}
pub mod service {
    #[cfg(feature = "session")]
    pub mod csrf;
    #[cfg(feature = "sqlx")]
    pub mod db;
    #[cfg(feature = "kalgan_i18n")]
    pub mod i18n;
    #[cfg(feature = "mailer")]
    pub mod mailer;
    #[cfg(feature = "services")]
    pub mod password;
    #[cfg(feature = "services")]
    pub mod token;
    pub mod url;
}
mod server {
    pub(crate) mod tcp_listener;
    pub(crate) mod thread_pool;
    pub(crate) mod worker;
}
pub mod storage {
    pub mod cookie;
    #[cfg(feature = "session")]
    pub mod session;
}
pub mod settings;
#[cfg(feature = "tera")]
pub mod template;
use crate::{
    handler::middleware::Outcome,
    http::{request::Request, response::Response},
    server::tcp_listener,
};
#[cfg(feature = "cache")]
pub use kalgan_cache;
use chrono::{offset::Utc, NaiveTime};
use log::trace;
use std::{collections::HashMap, sync::Mutex};

/// Stores the current time used to refresh the config parameters and version static files in templates.
struct Refresh {
    time: NaiveTime,
}
#[cfg(feature = "tera")]
/// Stores the custom tera configuration.
struct TeraConfig {
    config: Option<fn(&mut tera::Tera) -> &mut tera::Tera>,
}
lazy_static! {
    pub(crate) static ref CONFIG: Mutex<kalgan_config::Config> = Mutex::new(kalgan_config::Config{ collection: HashMap::new() });
    pub(crate) static ref ROUTES: Mutex<kalgan_router::Router> = Mutex::new(kalgan_router::Router{ collection: Vec::new() });
    pub(crate) static ref REFRESH: Mutex<Refresh> = Mutex::new(Refresh { time: Utc::now().time() });
}
#[cfg(feature = "tera")]
lazy_static! {
    pub(crate) static ref TEMPLATES: tera::Tera = {
        template::get_tera(&settings::get_string("tera.path").unwrap()).unwrap()
    };
    pub(crate) static ref TERA_CONFIG: Mutex<TeraConfig> = Mutex::new(TeraConfig { config: None });
}
#[cfg(feature = "kalgan_i18n")]
lazy_static! {
    pub(crate) static ref MESSAGES: Mutex<kalgan_i18n::Messages> = Mutex::new(kalgan_i18n::Messages{ collection: HashMap::new() });
}
/// Parses configuration parameters, routes and translation messages and finally starts the http server.
pub fn run(
    settings_file_path: &'static str,
    controller: fn(&Request, &str) -> Result<Response, String>,
    middleware: Option<fn(&mut Request, &str) -> Result<Outcome, String>>,
) {
    set_config(settings_file_path);
    set_routes();
    #[cfg(feature = "kalgan_i18n")]
    {
        set_messages();
    }
    tcp_listener::start(settings_file_path, controller, middleware);
}
#[cfg(feature = "tera")]
/// Sets custom tera configuration.
pub fn set_tera_config(tera_config: fn(&mut tera::Tera) -> &mut tera::Tera) {
    let mut tera_static = TERA_CONFIG.lock().unwrap();
    tera_static.config = Some(tera_config);
    std::mem::drop(tera_static);
}
/// Parses settings parameter files.
pub(crate) fn set_config(settings_file_path: &str) {
    let mut config_static = CONFIG.lock().unwrap();
    config_static.collection = kalgan_config::Config::new(&settings_file_path).collection;
    trace!("{:?}", &config_static);
    std::mem::drop(config_static);
}
/// Parses routing files.
fn set_routes() {
    let mut route_static = ROUTES.lock().unwrap();
    route_static.collection =
        kalgan_router::Router::new(&settings::get_string("router.path").unwrap()).collection;
    trace!("{:?}", &route_static);
    std::mem::drop(route_static);
}
#[cfg(feature = "kalgan_i18n")]
/// Parses translation messages files.
fn set_messages() {
    let mut messages_static = MESSAGES.lock().unwrap();
    messages_static.collection =
        kalgan_i18n::Messages::new(&settings::get_string("i18n.path").unwrap()).collection;
    trace!("{:?}", &messages_static);
    std::mem::drop(messages_static);
}
#[cfg(feature = "test")]
/// Parses settings parameter files used in testing.
pub fn mock_settings(settings_file_path: &str) {
    set_config(settings_file_path);
}
#[cfg(feature = "test")]
/// Parses routing files used in testing.
pub fn mock_routes() {
    set_routes();
}
#[cfg(feature = "test")]
/// Parses translation messages files used in testing.
pub fn mock_i18n() {
    set_messages();
}
#[cfg(test)]
pub mod tests {
    use super::*;
    pub fn set_config() {
        mock_settings("tests/mock/settings.yaml");
    }
}