use std::collections::hash_map::DefaultHasher; use std::future::Future; use std::hash::{Hash, Hasher}; use anyhow::Result; use rand::distributions::Alphanumeric; use rand::Rng; use regex::Regex; use tokio::task::JoinHandle; use validator::ValidationError; #[inline] pub fn spawn_nonessential(future: impl Future> + Send + 'static) -> JoinHandle<()> { tokio::spawn(async { if let Err(error) = future.await { log_error(error); } }) } #[inline] pub fn run_nonessential(block: impl FnOnce() -> Result<()>) { if let Err(error) = block() { log_error(error); } } #[inline] pub fn log_error(error: anyhow::Error) { log::error!("{:#}", error); } pub fn validate_hass_id(value: &str) -> Result<(), ValidationError> { if Regex::new(r"^[a-zA-Z0-9]+(_[a-zA-Z0-9]+)*$").unwrap().is_match(value) { Ok(()) } else { Err(ValidationError::new("does not match regex")) } } pub fn generate_alphanumeric_id(length: usize) -> String { rand::thread_rng().sample_iter(&Alphanumeric).take(length).map(char::from).collect() } pub fn hash_string_to_u32(string: &str) -> u32 { let mut hasher = DefaultHasher::new(); string.hash(&mut hasher); (hasher.finish() / 2) as u32 }