Skip to content

Commit

Permalink
add tardis_static macro
Browse files Browse the repository at this point in the history
  • Loading branch information
4t145 committed Oct 17, 2023
1 parent d4235e6 commit 6b2b8db
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 15 deletions.
25 changes: 14 additions & 11 deletions tardis/src/basic/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ use std::ops::Deref;

use regex::Regex;

use crate::utils::mapper::{Base64Decode, Base64Encode, Mapped, Trim};

lazy_static! {
static ref R_PHONE: Regex = Regex::new(r"^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$").expect("Regular parsing error");
static ref R_MAIL: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
use crate::{
tardis_static,
utils::mapper::{Base64Decode, Base64Encode, Mapped, Trim},
};

tardis_static! {
pub r_phone: Regex = Regex::new(r"^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$").expect("Regular parsing error");
pub r_mail: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
.expect("Regular parsing error");
static ref R_CODE_NCS: Regex = Regex::new(r"^[a-z0-9_]+$").expect("Regular parsing error");
static ref R_CODE_CS: Regex = Regex::new(r"^[A-Za-z0-9_]+$").expect("Regular parsing error");
pub r_code_ncs: Regex = Regex::new(r"^[a-z0-9_]+$").expect("Regular parsing error");
pub r_code_cs: Regex = Regex::new(r"^[A-Za-z0-9_]+$").expect("Regular parsing error");
}

static BASE62: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Expand Down Expand Up @@ -42,24 +45,24 @@ pub struct TardisField;
impl TardisField {
/// Determine if it is a cell phone number (only supports mainland China) / 判断是否是手机号(仅支持中国大陆)
pub fn is_phone(&self, phone: &str) -> bool {
R_PHONE.is_match(phone)
r_phone().is_match(phone)
}

/// Determine if it is a email / 判断是否是邮箱
pub fn is_mail(&self, mail: &str) -> bool {
R_MAIL.is_match(mail)
r_mail().is_match(mail)
}

/// Determine if it contains only numbers, lowercase letters and underscores /
/// 判断是否只包含数字、小写字母及下划线
pub fn is_code_cs(&self, str: &str) -> bool {
R_CODE_CS.is_match(str)
r_code_cs().is_match(str)
}

/// Determine if only numbers, upper and lower case letters and underscores are included /
/// 判断是否只包含数字、大小写字母及下划线
pub fn is_code_ncs(&self, str: &str) -> bool {
R_CODE_NCS.is_match(str)
r_code_ncs().is_match(str)
}

/// Generate NanoId / 生成NanoId
Expand Down
3 changes: 1 addition & 2 deletions tardis/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ pub mod cached_json_value;
pub(crate) use cached_json_value::*;
pub mod tardis_component;
pub(crate) use tardis_component::*;
// pub mod hot;
pub mod initializer;

pub mod mapper;
pub mod tardis_static;
84 changes: 84 additions & 0 deletions tardis/src/utils/tardis_static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/// A macro to create a static variable that is lazily initialized, using [`std::sync::OnceLock`] or [`tokio::sync::OnceCell`] to store.
/// # Examples
/// ```ignore
/// tardis_static! {
/// pub config: Config = Config::new();
/// }
///
/// // then use it as a function, it will return a static reference.
/// let config = config();
/// ```
///
/// if you want to initialize the static variable asynchronously, you can use `async` keyword.
/// ```ignore
/// tardis_static! {
/// pub async x: Config = async {
/// wait_other_async().await;
/// retrive_config().await
/// };
/// }
/// ```
/// for those type that implement [`Default`] trait, you emit the initial value.
/// ```ignore
/// tardis_static! {
/// pub config: Config;
/// }
///
/// ```
#[macro_export]
macro_rules! tardis_static {
() => {
};
($(#[$attr:meta])* $vis:vis async $ident:ident :$Type:ty = $init: expr; $($rest: tt)*) => {
$(#[$attr])*
$vis async fn $ident() -> &'static $Type {
use tokio::sync::OnceCell;
static STATIC_VAL: OnceCell<$Type> = OnceCell::const_new();

STATIC_VAL.get_or_init(|| $init).await
}
$crate::tardis_static!($($rest)*);
};

($(#[$attr:meta])* $vis:vis $ident:ident :$Type:ty = $init: expr; $($rest: tt)*) => {
$(#[$attr])*
$vis fn $ident() -> &'static $Type {
use std::sync::OnceLock;
static STATIC_VAL: OnceLock<$Type> = OnceLock::new();

STATIC_VAL.get_or_init(|| $init)
}
$crate::tardis_static!($($rest)*);
};

($(#[$attr:meta])* $vis:vis $ident:ident :$Type:ty; $($rest: tt)*) => {
$crate::tardis_static!($(#[$attr])* $vis $ident: $Type = Default::default(); $($rest)*);
};
}

#[cfg(test)]
#[test]
#[allow(dead_code)]
fn test_tardis_static_macro() {
#[derive(Default, Clone)]
struct Config {}

tardis_static! {
config: Config = Config::default();
}
async fn wait_other_async() {}
async fn retrive_config() -> Config {
config().clone()
}
tardis_static! {
async async_config: Config = async {
wait_other_async().await;
retrive_config().await
};
}

tardis_static! {
config_defualt: Config;
}
}
4 changes: 2 additions & 2 deletions tardis/src/web/web_resp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,5 @@ where
pub records: Vec<T>,
}

#[derive(Object, Deserialize, Serialize, Clone, Debug)]
pub struct Void {}
#[derive(Object, Deserialize, Serialize, Clone, Debug, Default, Copy)]
pub struct Void;
8 changes: 8 additions & 0 deletions tardis/src/web/web_server/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl<T, _MW, _D> WebServerModule<T, _MW, _D> {
}
}

/// set the data for this module, this function will replace the previous data
pub fn data<D>(self, data: D) -> WebServerModule<T, _MW, D> {
WebServerModule {
apis: self.apis,
Expand All @@ -118,6 +119,7 @@ impl<T, _MW, _D> WebServerModule<T, _MW, _D> {
}
}

/// set the middleware for this module, this function will replace the previous middleware
pub fn middleware<MW>(self, middleware: MW) -> WebServerModule<T, MW, _D> {
WebServerModule {
apis: self.apis,
Expand All @@ -127,6 +129,7 @@ impl<T, _MW, _D> WebServerModule<T, _MW, _D> {
}
}

/// set the options for this module, this function will replace the previous options
pub fn options(self, options: WebServerModuleOption) -> Self {
WebServerModule { options, ..self }
}
Expand Down Expand Up @@ -173,6 +176,7 @@ impl Default for WebServerGrpcModule {

#[cfg(feature = "web-server-grpc")]
impl<_MW, _D> WebServerGrpcModule<_MW, _D> {
/// set the data for this module, this function will replace the previous data
pub fn data<D>(self, data: D) -> WebServerGrpcModule<_MW, D> {
WebServerGrpcModule {
data: Some(data),
Expand All @@ -182,6 +186,7 @@ impl<_MW, _D> WebServerGrpcModule<_MW, _D> {
}
}

/// set the middleware for this module, this function will replace the previous middleware
pub fn middleware<MW>(self, middleware: MW) -> WebServerGrpcModule<MW, _D> {
WebServerGrpcModule {
data: self.data,
Expand All @@ -194,6 +199,7 @@ impl<_MW, _D> WebServerGrpcModule<_MW, _D> {

#[cfg(feature = "web-server-grpc")]
impl<MW, D> WebServerGrpcModule<MW, D> {
/// with new grpc service T, T must be a [`poem_grpc::Service`]
pub fn with_grpc_service<T: Clone>(mut self, service: T) -> Self
where
T: poem::IntoEndpoint<Endpoint = BoxEndpoint<'static, poem::Response>> + poem_grpc::Service + Send + Sync + 'static,
Expand All @@ -202,6 +208,8 @@ impl<MW, D> WebServerGrpcModule<MW, D> {
self.grpc_router_mapper = Arc::new(move |route| previous_mapper(route).add_service(service.clone()));
self
}

/// with grpc descriptor
pub fn with_descriptor(mut self, descriptor: Vec<u8>) -> Self {
self.descriptor_sets.push(descriptor);
self
Expand Down

0 comments on commit 6b2b8db

Please sign in to comment.