| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | 
							- use r2d2_sqlite::SqliteConnectionManager;
 
- use r2d2::Pool;
 
- #[macro_use]
 
- use rusqlite::params;
 
- use std::sync::Arc;
 
- use std::fs::File;
 
- use std::io::{self, BufRead};
 
- use rand::thread_rng;
 
- use rand::seq::SliceRandom;
 
- use rand::distributions::{Distribution, WeightedIndex};
 
- pub fn create_array_source(filename: &str) -> Arc<dyn DataSource<String>> {
 
-     let file = File::open(filename).unwrap();
 
-     let lines = io::BufReader::new(file).lines();
 
-     let mut questions: Vec<String> = Vec::new();
 
-     for line in lines {
 
-         if let Ok(l) = line {
 
-             questions.push(l);
 
-         }
 
-     }
 
-     Arc::new(ArraySource::create(questions))
 
- }
 
- pub trait DataSource<T> {
 
-     fn get_ith(&self, i: usize) -> Option<T>;
 
-     fn len(&self) -> usize;
 
- }
 
- pub struct ArraySource<T> {
 
-     words: Vec<T>
 
- }
 
- impl<T: Clone> DataSource<T> for ArraySource<T> {
 
-     fn get_ith(&self, i: usize) -> Option<T> {
 
-         self.words.get(i).cloned()
 
-     }
 
-     fn len(&self) -> usize {
 
-         self.words.len()
 
-     }
 
- }
 
- impl<T> ArraySource<T> {
 
-     pub fn create(words: Vec<T>) -> Self {
 
-         ArraySource {
 
-             words
 
-         }
 
-     }
 
- }
 
- pub struct SqliteSource {
 
-     pool: Pool<SqliteConnectionManager>
 
- }
 
- impl DataSource<String> for SqliteSource {
 
-     fn get_ith(& self, i: usize) -> Option<String> {
 
-         match self.pool.get() {
 
-             Ok(p) => {
 
-                 let r: rusqlite::Result<String> = p.query_row(
 
-                     "SELECT question
 
-                      FROM questions
 
-                      WHERE id=?1;",
 
-                      params![i as i32],
 
-                     |row| row.get(0));
 
-                 r.ok()
 
-             },
 
-             Err(_) => None
 
-         }
 
-     }
 
-     fn len(&self) -> usize {
 
-         match self.pool.get() {
 
-             Ok(p) => {
 
-                 let r: rusqlite::Result<i32> = p.query_row(
 
-                     "SELECT COUNT(*)
 
-                      FROM questions;",
 
-                      rusqlite::NO_PARAMS,
 
-                     |row| row.get(0));
 
-                 r.unwrap_or(0) as usize
 
-             },
 
-             Err(_) => 0
 
-         }
 
-     }
 
- }
 
- impl SqliteSource {
 
-     pub fn open(db_name: &str) -> Result<Self, r2d2::Error> {
 
-         Ok(SqliteSource {
 
-             pool: Pool::new(SqliteConnectionManager::file(db_name))?
 
-         })
 
-     }
 
- }
 
- pub struct Shuffler<T> {
 
-     source: Arc<dyn DataSource<T>>,
 
-     permutation: Vec<usize>,
 
-     index: usize
 
- }
 
- impl<T> Shuffler<T> {
 
-     pub fn create(source: Arc<dyn DataSource<T>>) -> Self {
 
-         let mut permutation = (0..source.len()).collect::<Vec<_>>();
 
-         permutation.shuffle(&mut thread_rng());
 
-         Self {
 
-             source,
 
-             permutation,
 
-             index: 0
 
-         }
 
-     }
 
-     pub fn get(&mut self) -> T {
 
-         let old_index = self.index;
 
-         self.index += 1;
 
-         if self.index >= self.permutation.len() {
 
-             self.index = 0;
 
-         }
 
-         self.source.get_ith(self.permutation[old_index]).unwrap()
 
-     }
 
- }
 
- pub struct LetterDistribution {
 
-     consonants: Vec<char>,
 
-     consonant_weights: WeightedIndex<f32>,
 
-     vowels: Vec<char>,
 
-     vowel_weights: WeightedIndex<f32>,
 
- }
 
- impl LetterDistribution {
 
-     pub fn create() -> Self {
 
-         Self {
 
-             consonants: vec![
 
-                 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z' 
 
-             ],
 
-             consonant_weights: WeightedIndex::new(vec![
 
-                 4.5f32,
 
-                 5.5f32,
 
-                 6.5f32,
 
-                 3.5f32,
 
-                 5.0f32,
 
-                 7.5f32,
 
-                 1.0f32,
 
-                 3.0f32,
 
-                 5.0f32,
 
-                 5.0f32,
 
-                 13.0f32,
 
-                 2.5f32,
 
-                 1.0f32,
 
-                 9.0f32,
 
-                 8.5f32,
 
-                 8.5f32,
 
-                 2.5f32,
 
-                 3.0f32,
 
-                 1.0f32,
 
-                 1.0f32,
 
-                 3.5f32,
 
-             ]).unwrap(),
 
-             vowels: vec!['A', 'E', 'I', 'O', 'U', 'Ä', 'Ö', 'Ü'],
 
-             vowel_weights: WeightedIndex::new(vec![
 
-                 17.0f32,
 
-                 32.0f32,
 
-                 22.0f32,
 
-                 10.0f32,
 
-                 13.0f32,
 
-                  2.0f32,
 
-                  2.0f32,
 
-                  2.0f32,
 
-             ]).unwrap()
 
-         }
 
-     }
 
-     pub fn get(&self, vowels: usize, consonants: usize) -> Vec<char> {
 
-         let mut result: Vec<char> = Vec::new();
 
-         let rng = &mut thread_rng();
 
-         for _i in 0..vowels {
 
-             result.push(self.vowels[self.vowel_weights.sample(rng)]);
 
-         }
 
-         for _i in 0..consonants {
 
-             result.push(self.consonants[self.consonant_weights.sample(rng)]);
 
-         }
 
-         return result;
 
-     }
 
- }
 
 
  |