1use std::collections::HashMap;
2
3use std::time::SystemTime;
4
5use std::sync::Mutex;
6
7use base64::display::Base64Display;
8use base64::prelude::*;
9use rand::thread_rng;
10
11use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey};
12use rsa::{PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey};
13use crate::get_local_timestamp;
15use chrono::offset::Local;
16use chrono::{DateTime, NaiveDateTime};
17use serde::{Deserialize, Deserializer};
18
19use super::AppConfig;
20
21pub struct ValuePaire {
22 value: String,
23 key: String,
24 timestamp: u64,
25 expired: u64,
26}
27
28lazy_static! {
29 pub static ref APP_DATA: Mutex<HashMap<String, ValuePaire>> = Mutex::new(HashMap::new());
30}
31
32pub fn global_app_data_resizing() {
36 let dts = APP_DATA.lock().unwrap();
37 let len = dts.len();
38 let mut keys = vec![];
39 if len > 10usize {
40 let t = get_local_timestamp();
41 let values = dts.values();
42
43 values.for_each(|f| {
44 let ts = f.timestamp + f.expired;
45 if t >= ts {
46 keys.push(f.key.clone());
48 }
49 });
50 }
51 drop(dts);
52
53 for key in keys {
54 global_app_data_remove(&key);
55 }
56}
57
58#[allow(dead_code)]
59pub fn global_app_data_insert(key: &str, val: &str) {
60 global_app_data_insert_with_expire(key, val, 1000 * 60);
64}
65
66#[allow(dead_code)]
67pub fn global_app_data_insert_with_expire(key: &str, val: &str, exp: u64) {
68 let value = ValuePaire {
72 value: val.to_owned(),
73 key: key.to_owned(),
74 timestamp: get_local_timestamp(),
75 expired: exp,
76 };
77
78 APP_DATA
79 .lock()
80 .as_mut()
81 .unwrap()
82 .insert(key.to_string(), value);
83
84 global_app_data_resizing();
85}
86
87#[allow(dead_code)]
88pub fn global_app_data_remove(key: &String) {
89 APP_DATA.lock().as_mut().unwrap().remove(key);
93}
94
95#[allow(dead_code)]
96pub fn global_app_data_get(key: &String) -> Option<String> {
97 let dt = APP_DATA.lock().unwrap();
98 let cp = dt.get(key);
99 if cp.is_none() {
100 None
101 } else {
102 let mpt = cp.unwrap();
103 if mpt.expired > 0 {
104 let tm = get_local_timestamp();
105 if tm > mpt.timestamp + mpt.expired {
106 global_app_data_remove(key);
107 return None;
108 }
109 }
110 Some(cp.unwrap().value.clone())
111 }
112}
113
114#[allow(dead_code)]
115pub fn rsa_decrypt_by_private_key(token: &String) -> Option<String> {
116 let private_key = AppConfig::get()
117 .lock()
118 .unwrap()
119 .to_owned()
120 .webserver_conf
121 .rsa_password_private_key;
122
123 let bs = match BASE64_STANDARD.decode(private_key) {
124 Ok(rs) => rs,
125 Err(_) => {
126 vec![]
127 }
128 };
129
130 let priv_key = match RsaPrivateKey::from_pkcs8_der(&bs) {
131 Ok(r) => Some(r),
132 Err(err) => {
133 log::warn!("Decode the Private Key with an error {}", err);
134 None
135 }
136 };
137
138 match priv_key {
139 Some(pkey) => {
140 let basedecode = match BASE64_STANDARD.decode(token) {
141 Ok(ts) => ts,
142 Err(_) => vec![],
143 };
144 let dcode = pkey.decrypt(PaddingScheme::PKCS1v15Encrypt, &basedecode);
145 match dcode {
146 Ok(rs) => match String::from_utf8(rs) {
147 Ok(text) => Some(text),
148 Err(err) => {
149 log::warn!("Convert to utf8 with an error {}", err);
150 None
151 }
152 },
153 Err(err) => {
154 log::warn!("Decode the token with an error {}", err.to_string());
155 None
156 }
157 }
158 }
159 None => None,
160 }
161}
162
163#[allow(dead_code)]
164pub fn rsa_encrypt_by_public_key(token: &String) -> Option<String> {
165 let public_key = AppConfig::get()
166 .lock()
167 .unwrap()
168 .to_owned()
169 .webserver_conf
170 .rsa_password_public_key;
171
172 let bs = match BASE64_STANDARD.decode(public_key) {
173 Ok(rs) => rs,
174 Err(_) => {
175 vec![]
176 }
177 };
178
179 let pub_key = match RsaPublicKey::from_public_key_der(&bs) {
180 Ok(r) => Some(r),
181 Err(err) => {
182 log::warn!("Decode the Private Key with an error {}", err);
183 None
184 }
185 };
186
187 match pub_key {
188 Some(pkey) => {
189 let mut rng = thread_rng();
190 let encoded = pkey.encrypt(&mut rng, PaddingScheme::PKCS1v15Encrypt, token.as_bytes());
191 match encoded {
192 Ok(rs) => {
193 let encodebase = Base64Display::new(&rs, &BASE64_STANDARD).to_string(); Some(encodebase)
195 }
196 Err(err) => {
197 log::warn!("Decode the token with an error {}", err.to_string());
198 None
199 }
200 }
201 }
202 None => None,
203 }
204}
205
206#[derive(Deserialize)]
207#[serde(untagged)] enum StrOrU64 {
209 None,
210 String(String),
211 U64(u64),
212}
213
214#[derive(Deserialize)]
215#[serde(untagged)] enum StrOrI64 {
217 None,
218 String(String),
219 I64(i64),
220}
221
222#[derive(Deserialize)]
223#[serde(untagged)] enum StrOrF64 {
225 None,
226 String(String),
227 F64(f64),
228}
229
230#[derive(Deserialize)]
231#[serde(untagged)] enum StrOrF32 {
233 None,
234 String(String),
235 F32(f32),
236}
237
238#[derive(Deserialize)]
239#[serde(untagged)] enum StrOrBool {
241 String(String),
242 I64(i64),
243 Bool(bool),
244 None,
245}
246
247#[allow(dead_code)]
248pub fn u64_from_str<'de, D>(deserializer: D) -> Result<u64, D::Error>
249where
250 D: Deserializer<'de>,
251{
252 Ok(match StrOrU64::deserialize(deserializer)? {
253 StrOrU64::String(v) => v.parse().unwrap_or_default(),
254 StrOrU64::U64(v) => v,
255 StrOrU64::None => 0u64,
256 })
257}
258
259#[allow(dead_code)]
260pub fn i64_from_str<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
261where
262 D: Deserializer<'de>,
263{
264 Ok(match StrOrI64::deserialize(deserializer)? {
265 StrOrI64::String(v) => match v.parse::<i64>() {
266 Ok(st) => Some(st),
267 Err(_) => None,
268 },
269 StrOrI64::I64(v) => Some(v),
270 StrOrI64::None => None,
271 })
272}
273
274#[allow(dead_code)]
275pub fn i32_from_str<'de, D>(deserializer: D) -> Result<Option<i32>, D::Error>
276where
277 D: Deserializer<'de>,
278{
279 Ok(match StrOrI64::deserialize(deserializer)? {
280 StrOrI64::String(v) => match v.parse::<i64>() {
281 Ok(st) => Some(st as i32),
282 Err(_) => None,
283 },
284 StrOrI64::I64(v) => Some(v as i32),
285 StrOrI64::None => None,
286 })
287}
288
289#[allow(dead_code)]
290pub fn f64_from_str<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
291where
292 D: Deserializer<'de>,
293{
294 Ok(match StrOrF64::deserialize(deserializer)? {
295 StrOrF64::String(v) => Some(v.parse().unwrap_or_default()),
296 StrOrF64::F64(v) => Some(v),
297 StrOrF64::None => None,
298 })
299}
300
301#[allow(dead_code)]
302pub fn f32_from_str<'de, D>(deserializer: D) -> Result<f32, D::Error>
303where
304 D: Deserializer<'de>,
305{
306 Ok(match StrOrF32::deserialize(deserializer)? {
307 StrOrF32::String(v) => v.parse().unwrap_or_default(),
308 StrOrF32::F32(v) => v,
309 StrOrF32::None => 0.0f32,
310 })
311}
312
313#[allow(dead_code)]
314pub fn bool_from_str<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
315where
316 D: Deserializer<'de>,
317{
318 Ok(match StrOrBool::deserialize(deserializer) {
319 Ok(t) => match t {
320 StrOrBool::String(v) => match v.parse::<bool>() {
321 Ok(tf) => Some(tf),
322 Err(err) => {
323 log::warn!("Parse erroor {}", err);
324 None
325 }
326 },
327 StrOrBool::I64(v) => Some(v != 0i64),
328 StrOrBool::Bool(v) => Some(v),
329 StrOrBool::None => Some(false),
330 },
331 Err(err) => {
332 log::warn!("Deserializer erroor {}", err);
333 None
334 }
335 })
336}
337
338pub fn num_to_string(n: i64) -> String {
339 let base_codec = [
340 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
341 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '7', '8', '9',
342 ];
343 let len = base_codec.len() as i64;
344 let mut t = n;
345 let mut result = "".to_string();
346 while t > 0 {
347 let idx = (t % len) as usize;
348 let ch = base_codec[idx];
349 t /= len;
350 result.insert(0, ch);
351 }
352 result
353}
354
355pub fn number_to_string(n: i64) -> String {
356 let base_codec = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
357 let len = base_codec.len() as i64;
358 let mut t = n;
359 let mut result = "".to_string();
360 while t > 0 {
361 let idx = (t % len) as usize;
362 let ch = base_codec[idx];
363 t /= len;
364 result.insert(0, ch);
365 }
366 result
367}
368
369pub fn generate_rand_string(len: usize) -> String {
370 let mut retkey = "".to_string();
371
372 while retkey.len() < len {
373 let rng = rand::random::<u16>();
374 let key = num_to_string(rng as i64);
375 retkey += key.as_str();
376 }
377
378 retkey.chars().take(len).collect()
379}
380
381pub fn generate_rand_numberstring(len: usize) -> String {
382 let mut retkey = "".to_string();
383
384 while retkey.len() < len {
385 let rng = rand::random::<u16>();
386 let key = number_to_string(rng as i64);
387 retkey += key.as_str();
388 }
389
390 retkey.chars().take(len).collect()
391}
392
393#[allow(dead_code)]
394pub fn num_to_string_v2(n: i64) -> String {
395 let base_codec = [
396 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't',
397 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
398 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7',
399 '8', '9',
400 ];
401 let len = base_codec.len() as i64;
402 let mut t = n;
403 let mut result = "".to_string();
404 while t > 0 {
405 let idx = (t % len) as usize;
406 let ch = base_codec[idx];
407 t /= len;
408 result.insert(0, ch);
409 }
410 result
411}
412#[allow(dead_code)]
413pub fn f32_to_decimal(f: f32) -> Option<rbatis::Decimal> {
414 match rbatis::Decimal::from_str(format!("{:.2}", f).as_str()) {
415 Ok(r) => Some(r),
416 Err(_) => None,
417 }
418}
419
420#[allow(dead_code)]
421pub fn f64_to_decimal(f: f64) -> Option<rbatis::Decimal> {
422 println!("f64: value: {:.2}, {}", f.clone(), f.clone());
423 match rbatis::Decimal::from_str(format!("{:.2}", f).as_str()) {
424 Ok(r) => Some(r),
425 Err(_) => None,
426 }
427}
428
429#[allow(dead_code)]
430pub fn f64_to_decimal_v2(f: f64) -> Option<rbatis::Decimal> {
431 println!("f64: value: {:.2}, {}", f.clone(), f.clone());
432 let cff = if f < 0.01f64 { 0.00 } else { f };
433
434 match rbatis::Decimal::from_str(format!("{:.2}", cff).as_str()) {
435 Ok(r) => Some(r),
436 Err(_) => None,
437 }
438}
439
440#[allow(dead_code)]
441pub fn decimal_to_f32(dc: Option<rbatis::Decimal>) -> f32 {
442 dc.map(|r| r.to_string().parse::<f32>().unwrap_or_default())
443 .unwrap_or_default()
444}
445
446#[allow(dead_code)]
447pub fn decimal_to_f64(dc: Option<rbatis::Decimal>) -> f64 {
448 dc.map(|r| r.to_string().parse::<f64>().unwrap_or_default())
449 .unwrap_or_default()
450}
451
452#[allow(dead_code)]
453pub fn decimal_compare(dc: Option<rbatis::Decimal>, dc2: Option<rbatis::Decimal>) -> i64 {
454 let f1 = decimal_to_f64(dc);
455 let f2 = decimal_to_f64(dc2);
456
457 if f1 == f2 {
458 0i64
459 } else if f1 > f2 {
460 1i64
461 } else {
462 -1i64
463 }
464}
465
466#[allow(dead_code)]
467pub fn decimal_add(
468 dc: Option<rbatis::Decimal>,
469 dc2: Option<rbatis::Decimal>,
470 ng: bool,
471) -> Option<rbatis::Decimal> {
472 let f1 = decimal_to_f64(dc);
473 let f2 = decimal_to_f64(dc2);
474
475 if ng {
476 f64_to_decimal(f1 - f2)
477 } else {
478 f64_to_decimal(f1 + f2)
479 }
480}
481
482#[allow(dead_code)]
483pub fn make_decimal_negative(dc: Option<rbatis::Decimal>) -> Option<rbatis::Decimal> {
484 match dc {
485 Some(r) => match r.to_string().parse::<f32>() {
486 Ok(t) => f32_to_decimal(-t),
487 Err(_) => f32_to_decimal(0f32),
488 },
489 None => f32_to_decimal(0f32),
490 }
491}
492
493#[allow(dead_code)]
494pub fn int_to_decimal(val: &Option<i64>, mltp: f64) -> Option<rbatis::Decimal> {
495 if val.is_none() {
496 None
497 } else {
498 let fx = val.unwrap() as f64;
499 f64_to_decimal(fx / mltp)
500 }
501}
502
503#[allow(dead_code)]
504pub fn decimal_mult_decimal(
505 val: &Option<rbatis::Decimal>,
506 val2: &Option<rbatis::Decimal>,
507) -> Option<rbatis::Decimal> {
508 f64_to_decimal_v2(decimal_to_f64(val.clone()) * decimal_to_f64(val2.clone()))
509}
510
511#[allow(dead_code)]
512pub fn decimal_plus_decimal(
513 val: &Option<rbatis::Decimal>,
514 val2: &Option<rbatis::Decimal>,
515) -> Option<rbatis::Decimal> {
516 f64_to_decimal_v2(decimal_to_f64(val.clone()) + decimal_to_f64(val2.clone()))
517}
518
519#[allow(dead_code)]
520pub fn generate_rand_string_v2(len: usize) -> String {
521 let mut retkey = "".to_string();
522
523 while retkey.len() < len {
524 let rng = rand::random::<u16>();
525 let key = num_to_string_v2(rng as i64);
526 retkey += key.as_str();
527 }
528
529 retkey.chars().take(len).collect()
530}
531
532#[allow(dead_code)]
533pub fn get_date_string() -> String {
534 let now = SystemTime::now();
535 let date: DateTime<Local> = now.into();
536 let fmt = format!("{}", date.format("%Y%m%d"));
537 fmt
538}
539
540#[allow(dead_code)]
541pub fn format_date_string(dt: &NaiveDateTime) -> String {
542 let fmt = format!("{}", dt.format("%Y年%m月%d日 %H:%M"));
543 fmt
544}
545
546pub fn get_url_encode(c: &str) -> String {
547 use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
548 const FRAGMENT: &AsciiSet = &CONTROLS
549 .add(b' ')
550 .add(b'"')
551 .add(b'<')
552 .add(b'>')
553 .add(b'`')
554 .add(b'+')
555 .add(b'=')
556 ;
558 utf8_percent_encode(c, FRAGMENT).to_string()
559}
560
561pub fn get_url_encode2(c: &str) -> String {
562 urlencoding::encode_binary(c.as_bytes()).into_owned()
563}