actix_cloud/
utils.rs

1use std::{
2    collections::HashSet,
3    env,
4    hash::Hash,
5    process::{Child, Command},
6};
7
8use rand::{
9    distributions::{Alphanumeric, Uniform},
10    thread_rng, Rng,
11};
12
13use crate::Result;
14
15/// Check whether iterator `iter` contains only unique values.
16pub fn is_unique<T>(iter: T) -> bool
17where
18    T: IntoIterator,
19    T::Item: Eq + Hash,
20{
21    let mut uniq = HashSet::new();
22    iter.into_iter().all(move |x| uniq.insert(x))
23}
24
25/// Check whether `t` type `T` is equal to default.
26pub fn is_default<T: Default + PartialEq>(t: &T) -> bool {
27    *t == Default::default()
28}
29
30/// Get `n` bytes random string.
31/// `[a-zA-Z0-9]+`
32pub fn rand_string(n: usize) -> String {
33    thread_rng()
34        .sample_iter(&Alphanumeric)
35        .take(n)
36        .map(char::from)
37        .collect()
38}
39
40/// Get `n` bytes random hex string.
41/// `[a-f0-9]+`
42pub fn rand_string_hex(n: usize) -> String {
43    let mut rng = thread_rng();
44    let bytes: Vec<u8> = (0..n / 2).map(|_| rng.gen()).collect();
45    hex::encode(bytes)
46}
47
48/// Get `n` bytes random string (all printable ascii).
49pub fn rand_string_all(n: usize) -> String {
50    thread_rng()
51        .sample_iter(Uniform::new(char::from(33), char::from(126)))
52        .take(n)
53        .map(char::from)
54        .collect()
55}
56
57/// Restart the program and keep the argument.
58///
59/// Inherit the environment/io/working directory of current process.
60pub fn restart() -> Result<Child> {
61    Command::new(env::current_exe().unwrap())
62        .args(env::args().skip(1))
63        .spawn()
64        .map_err(Into::into)
65}
66
67#[cfg(feature = "rustls")]
68/// Load SSL certificate and key.
69pub fn load_rustls_config<P: AsRef<std::path::Path>>(
70    cert: P,
71    key: P,
72) -> Result<rustls::ServerConfig> {
73    rustls::crypto::aws_lc_rs::default_provider()
74        .install_default()
75        .unwrap();
76    let config = rustls::ServerConfig::builder().with_no_client_auth();
77    let cert_chain =
78        rustls_pemfile::certs(&mut std::io::BufReader::new(std::fs::File::open(cert)?))
79            .collect::<Result<Vec<_>, _>>()?;
80    let mut key_chain =
81        rustls_pemfile::pkcs8_private_keys(&mut std::io::BufReader::new(std::fs::File::open(key)?))
82            .map(|v| v.map(rustls::pki_types::PrivateKeyDer::Pkcs8))
83            .collect::<Result<Vec<_>, _>>()?;
84
85    let Some(private_key) = key_chain.pop() else {
86        anyhow::bail!("Cannot find PKCS 8 private key");
87    };
88
89    config
90        .with_single_cert(cert_chain, private_key)
91        .map_err(Into::into)
92}