Skip to content
Snippets Groups Projects
utils.rs 2.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • timokoesters's avatar
    timokoesters committed
    use argon2::{Config, Variant};
    
    use sled::IVec;
    
    use std::{
        convert::TryInto,
        time::{SystemTime, UNIX_EPOCH},
    };
    
    pub fn millis_since_unix_epoch() -> u64 {
        SystemTime::now()
    
            .duration_since(UNIX_EPOCH)
    
            .expect("time is valid")
    
            .as_millis() as u64
    
    timokoesters's avatar
    timokoesters committed
    
    
    pub fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
    
        let number = match old.map(|bytes| bytes.try_into()) {
            Some(Ok(bytes)) => {
                let number = u64::from_be_bytes(bytes);
    
            _ => 1, // Start at one. since 0 should return the first event in the db
    
    timokoesters's avatar
    timokoesters committed
    
    
        Some(number.to_be_bytes().to_vec())
    
    timokoesters's avatar
    timokoesters committed
    }
    
    
    timokoesters's avatar
    timokoesters committed
    pub fn generate_keypair(old: Option<&[u8]>) -> Option<Vec<u8>> {
    
        Some(old.map(|s| s.to_vec()).unwrap_or_else(|| {
            ruma::signatures::Ed25519KeyPair::generate()
                .expect("Ed25519KeyPair generation always works (?)")
        }))
    
    timokoesters's avatar
    timokoesters committed
    }
    
    
    pub fn u64_from_bytes(bytes: &[u8]) -> Result<u64, std::array::TryFromSliceError> {
        let array: [u8; 8] = bytes.try_into()?;
        Ok(u64::from_be_bytes(array))
    
    timokoesters's avatar
    timokoesters committed
    }
    
    
    pub fn string_from_bytes(bytes: &[u8]) -> Result<String, std::string::FromUtf8Error> {
        String::from_utf8(bytes.to_vec())
    
    timokoesters's avatar
    timokoesters committed
    }
    
    
    pub fn random_string(length: usize) -> String {
        thread_rng()
            .sample_iter(&rand::distributions::Alphanumeric)
            .take(length)
            .collect()
    }
    
    gnieto's avatar
    gnieto committed
    
    /// Calculate a new hash for the given password
    
    pub fn calculate_hash(password: &str) -> Result<String, argon2::Error> {
    
    gnieto's avatar
    gnieto committed
        let hashing_config = Config {
            variant: Variant::Argon2id,
            ..Default::default()
        };
    
        let salt = random_string(32);
    
    timokoesters's avatar
    timokoesters committed
        argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &hashing_config)
    }
    
    
    pub fn common_elements(
        mut iterators: impl Iterator<Item = impl Iterator<Item = IVec>>,
    ) -> Option<impl Iterator<Item = IVec>> {
        let first_iterator = iterators.next()?;
        let mut other_iterators = iterators.map(|i| i.peekable()).collect::<Vec<_>>();
    
        Some(first_iterator.filter(move |target| {
            other_iterators
                .iter_mut()
                .map(|it| {
                    while let Some(element) = it.peek() {
                        if element > target {
                            return false;
                        } else if element == target {
                            return true;
                        } else {
                            it.next();
                        }
                    }
    
                    false
                })
                .all(|b| b)
        }))
    }