libspmg 0.2.1

Secure password manager library
Documentation

use rand::{thread_rng, Rng};
use std::fs;
use std::path::Path;

pub struct PwdGen;

impl PwdGen {
    pub fn read_charset<P: AsRef<Path>>(path: P) -> Result<Vec<char>, std::io::Error> {
        let contents = fs::read_to_string(path)?;
        Ok(contents.trim().chars().collect())
    }

    pub fn random(len: usize, charset: &[char]) -> String {
        let mut rng = thread_rng();
        let random_password: String = (0..len)
        .map(|_| {
            let idx = rng.gen_range(0..charset.len());
            charset[idx]
        })
        .collect();
        random_password
    }

    pub fn add_padding(min_len: usize, max_len: usize, charset: &[char], password: String) -> String {
        let mut rng = thread_rng();
        let pad_len = rng.gen_range(min_len..=max_len);
        let padding = PwdGen::random(pad_len, charset);
        format!("P{:02}C{}{}", pad_len, padding, password)
    }

    pub fn strip_padding(padded: &str) -> Option<String> {
        if !padded.starts_with('P') {
            return Some(String::from(padded));
        }
        let c_index = padded.find('C')?;
        let len_str = &padded[1..c_index];
        let pad_len: usize = len_str.parse().ok()?;
        let password_start = c_index + 1 + pad_len;

        if padded.len() < password_start {
            return None;
        }

        Some(padded[password_start..].to_string())
    }
}