new-home-proxy 0.1.2

This is a part of the New Home IoT System. It is used to make the core available in the www.
//! This module contains a random name generator.
//! It gets feed with files that contain predefined first and last names.
//! The random index for the names is get via the /dev/random character device which makes this
//! generator **incompatible with Windows!**

use std::fs::File;
use std::intrinsics::transmute;
use std::io::Read;

const FIRST_NAMES: &str = include_str!("../../resources/firstnames.txt");
const LAST_NAMES: &str = include_str!("../../resources/lastnames.txt");

pub struct NameGenerator {
    firstnames: Vec<String>,
    lastnames: Vec<String>,
}

impl NameGenerator {
    pub fn new() -> Self {
        Self {
            firstnames: String::from(FIRST_NAMES)
                .split("\n")
                .map(String::from)
                .collect(),
            lastnames: String::from(LAST_NAMES)
                .split("\n")
                .map(String::from)
                .collect(),
        }
    }

    pub fn generate_name(&self, firstnames_amount: i32) -> String {
        let mut firstnames: Vec<String> = vec![];
        let firstnames_count = self.firstnames.len() - 1;

        for _ in 0..firstnames_amount {
            let index = self.get_random_number(0, firstnames_count as u32);
            let name = match self.firstnames.get(index as usize) {
                Some(name) => name.clone(),
                None => String::new(),
            };

            firstnames.push(name);
        }

        let index = self.get_random_number(0, (self.lastnames.len() - 1) as u32);
        let lastname = match self.lastnames.get(index as usize) {
            Some(name) => name.clone(),
            None => String::new(),
        };

        format!(
            "{}-{}",
            firstnames
                .iter()
                .map(|string| string.to_lowercase())
                .collect::<Vec<String>>()
                .join("-"),
            lastname.to_lowercase()
        )
    }

    fn get_random_number(&self, from: u32, to: u32) -> u32 {
        let mut sys_random = File::open("/dev/urandom").unwrap();
        let mut number = [0u8; 4];
        sys_random.read_exact(&mut number).unwrap_or_default();

        let number: u32 = unsafe { transmute(number) };

        let random_float = number as f64 / std::u32::MAX as f64;

        (random_float * ((to - from) + from) as f64).ceil() as u32
    }
}