Skip to main content

fusion_common/
string.rs

1use base64ct::{Base64UrlUnpadded, Encoding};
2use rand::{Rng, distr::Alphanumeric, rng};
3use serde::{Deserializer, Serializer, de::Visitor};
4
5use crate::{Error, Result};
6
7pub fn repeat_str(s: &str, n: usize) -> String {
8  let mut v = String::with_capacity(s.len() * n);
9  for _ in 0..n {
10    v.push_str(s);
11  }
12  v
13}
14
15pub fn repeat_char(c: char, n: usize) -> String {
16  let mut v = String::with_capacity(n);
17  for _ in 0..n {
18    v.push(c);
19  }
20  v
21}
22
23pub fn random_string(n: usize) -> String {
24  rng().sample_iter(Alphanumeric).take(n).map(char::from).collect()
25}
26
27pub fn b64u_encode(content: impl AsRef<[u8]>) -> String {
28  Base64UrlUnpadded::encode_string(content.as_ref())
29}
30
31pub fn b64u_decode(b64u: &str) -> Result<Vec<u8>> {
32  Base64UrlUnpadded::decode_vec(b64u).map_err(|_| Error::FailToB64uDecode(format!("Input string: {b64u}")))
33}
34
35pub fn b64u_decode_to_string(b64u: &str) -> Result<String> {
36  b64u_decode(b64u)
37    .ok()
38    .and_then(|r| String::from_utf8(r).ok())
39    .ok_or(Error::FailToB64uDecode(format!("Input string: {b64u}")))
40}
41
42pub fn deser_str_to_vec_u8<'de, D>(d: D) -> core::result::Result<Vec<u8>, D::Error>
43where
44  D: Deserializer<'de>,
45{
46  struct StrToVecU8;
47  impl Visitor<'_> for StrToVecU8 {
48    type Value = Vec<u8>;
49
50    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
51      formatter.write_str("expect 'str'.")
52    }
53
54    fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
55    where
56      E: serde::de::Error,
57    {
58      Ok(v.as_bytes().into())
59    }
60  }
61
62  d.deserialize_str(StrToVecU8)
63}
64
65pub fn ser_vec_u8_to_str<S>(v: &[u8], s: S) -> core::result::Result<S::Ok, S::Error>
66where
67  S: Serializer,
68{
69  let string = std::str::from_utf8(v).map_err(serde::ser::Error::custom)?;
70  s.serialize_str(string)
71}
72
73/// 对需要保密的数据进行脱敏
74pub fn ser_str_secret<S>(v: &str, s: S) -> core::result::Result<S::Ok, S::Error>
75where
76  S: Serializer,
77{
78  s.serialize_str(v)
79}
80
81pub fn ser_opt_str_secret<S>(v: Option<String>, s: S) -> core::result::Result<S::Ok, S::Error>
82where
83  S: Serializer,
84{
85  match v {
86    Some(v) => s.serialize_str(&v),
87    None => s.serialize_none(),
88  }
89}