datasource.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. use r2d2_sqlite::SqliteConnectionManager;
  2. use r2d2::Pool;
  3. #[macro_use]
  4. use rusqlite::params;
  5. use std::sync::Arc;
  6. use std::fs::File;
  7. use std::io::{self, BufRead};
  8. use rand::thread_rng;
  9. use rand::seq::SliceRandom;
  10. use rand::distributions::{Distribution, WeightedIndex};
  11. pub fn create_array_source(filename: &str) -> Arc<dyn DataSource<String>> {
  12. let file = File::open(filename).unwrap();
  13. let lines = io::BufReader::new(file).lines();
  14. let mut questions: Vec<String> = Vec::new();
  15. for line in lines {
  16. if let Ok(l) = line {
  17. questions.push(l);
  18. }
  19. }
  20. Arc::new(ArraySource::create(questions))
  21. }
  22. pub trait DataSource<T> {
  23. fn get_ith(&self, i: usize) -> Option<T>;
  24. fn len(&self) -> usize;
  25. }
  26. pub struct ArraySource<T> {
  27. words: Vec<T>
  28. }
  29. impl<T: Clone> DataSource<T> for ArraySource<T> {
  30. fn get_ith(&self, i: usize) -> Option<T> {
  31. self.words.get(i).cloned()
  32. }
  33. fn len(&self) -> usize {
  34. self.words.len()
  35. }
  36. }
  37. impl<T> ArraySource<T> {
  38. pub fn create(words: Vec<T>) -> Self {
  39. ArraySource {
  40. words
  41. }
  42. }
  43. }
  44. pub struct SqliteSource {
  45. pool: Pool<SqliteConnectionManager>
  46. }
  47. impl DataSource<String> for SqliteSource {
  48. fn get_ith(& self, i: usize) -> Option<String> {
  49. match self.pool.get() {
  50. Ok(p) => {
  51. let r: rusqlite::Result<String> = p.query_row(
  52. "SELECT question
  53. FROM questions
  54. WHERE id=?1;",
  55. params![i as i32],
  56. |row| row.get(0));
  57. r.ok()
  58. },
  59. Err(_) => None
  60. }
  61. }
  62. fn len(&self) -> usize {
  63. match self.pool.get() {
  64. Ok(p) => {
  65. let r: rusqlite::Result<i32> = p.query_row(
  66. "SELECT COUNT(*)
  67. FROM questions;",
  68. rusqlite::NO_PARAMS,
  69. |row| row.get(0));
  70. r.unwrap_or(0) as usize
  71. },
  72. Err(_) => 0
  73. }
  74. }
  75. }
  76. impl SqliteSource {
  77. pub fn open(db_name: &str) -> Result<Self, r2d2::Error> {
  78. Ok(SqliteSource {
  79. pool: Pool::new(SqliteConnectionManager::file(db_name))?
  80. })
  81. }
  82. }
  83. pub struct Shuffler<T> {
  84. source: Arc<dyn DataSource<T>>,
  85. permutation: Vec<usize>,
  86. index: usize
  87. }
  88. impl<T> Shuffler<T> {
  89. pub fn create(source: Arc<dyn DataSource<T>>) -> Self {
  90. let mut permutation = (0..source.len()).collect::<Vec<_>>();
  91. permutation.shuffle(&mut thread_rng());
  92. Self {
  93. source,
  94. permutation,
  95. index: 0
  96. }
  97. }
  98. pub fn get(&mut self) -> T {
  99. let old_index = self.index;
  100. self.index += 1;
  101. if self.index >= self.permutation.len() {
  102. self.index = 0;
  103. }
  104. self.source.get_ith(self.permutation[old_index]).unwrap()
  105. }
  106. }
  107. pub struct LetterDistribution {
  108. consonants: Vec<char>,
  109. consonant_weights: WeightedIndex<f32>,
  110. vowels: Vec<char>,
  111. vowel_weights: WeightedIndex<f32>,
  112. }
  113. impl LetterDistribution {
  114. pub fn create() -> Self {
  115. Self {
  116. consonants: vec![
  117. 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z'
  118. ],
  119. consonant_weights: WeightedIndex::new(vec![
  120. 4.5f32,
  121. 5.5f32,
  122. 6.5f32,
  123. 3.5f32,
  124. 5.0f32,
  125. 7.5f32,
  126. 1.0f32,
  127. 3.0f32,
  128. 5.0f32,
  129. 5.0f32,
  130. 13.0f32,
  131. 2.5f32,
  132. 1.0f32,
  133. 9.0f32,
  134. 8.5f32,
  135. 8.5f32,
  136. 2.5f32,
  137. 3.0f32,
  138. 1.0f32,
  139. 1.0f32,
  140. 3.5f32,
  141. ]).unwrap(),
  142. vowels: vec!['A', 'E', 'I', 'O', 'U', 'Ä', 'Ö', 'Ü'],
  143. vowel_weights: WeightedIndex::new(vec![
  144. 17.0f32,
  145. 32.0f32,
  146. 22.0f32,
  147. 10.0f32,
  148. 13.0f32,
  149. 2.0f32,
  150. 2.0f32,
  151. 2.0f32,
  152. ]).unwrap()
  153. }
  154. }
  155. pub fn get(&self, vowels: usize, consonants: usize) -> Vec<char> {
  156. let mut result: Vec<char> = Vec::new();
  157. let rng = &mut thread_rng();
  158. for _i in 0..vowels {
  159. result.push(self.vowels[self.vowel_weights.sample(rng)]);
  160. }
  161. for _i in 0..consonants {
  162. result.push(self.consonants[self.consonant_weights.sample(rng)]);
  163. }
  164. return result;
  165. }
  166. }