saved distribution for rand

This commit is contained in:
Dmitry Belyaev 2019-08-19 19:03:35 +03:00
parent d97b820363
commit 80ee37c2ee
Signed by: b4tman
GPG Key ID: 41A00BF15EA7E5F3

View File

@ -21,7 +21,8 @@ use actix_web::{
App, Error, HttpRequest, HttpResponse, HttpServer, Result, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
}; };
use rand::seq::IteratorRandom; use rand::distributions::Uniform;
use rand::Rng;
use ledb::{Options, Storage}; use ledb::{Options, Storage};
@ -102,6 +103,21 @@ struct Question {
struct AppState { struct AppState {
storage: Storage, storage: Storage,
template: tera::Tera, template: tera::Tera,
database_distribution: Uniform<u32>,
}
fn get_database_distribution(storage: &Storage) -> Uniform<u32> {
let collection = storage
.collection("questions")
.expect("collection \"questions\"");
let last_id = collection.last_id().expect("\"questions\" last_id");
rand::distributions::Uniform::new_inclusive(1u32, last_id)
}
fn random_question_id(database_distribution: &Uniform<u32>) -> u32 {
let mut rng = rand::thread_rng();
rng.sample(database_distribution)
} }
fn get_question(storage: &Storage, id: u32) -> Result<Option<Question>, Error> { fn get_question(storage: &Storage, id: u32) -> Result<Option<Question>, Error> {
@ -134,7 +150,12 @@ fn show_question_details(template_file: &str, data: web::Data<AppState>, id: web
if question.is_some() { if question.is_some() {
let question = question.unwrap(); let question = question.unwrap();
let body = data.template.render(template_file, &question).unwrap(); let mut context = serde_json::to_value(question).expect("question serialize");
if context.is_object() {
let next_id = random_question_id(&data.database_distribution);
context["next"] = serde_json::to_value(next_id).expect("question id serialize");
}
let body = data.template.render(template_file, &context).expect("template render - show_question_details");
Ok(HttpResponse::Ok().content_type("text/html").body(body)) Ok(HttpResponse::Ok().content_type("text/html").body(body))
} else { } else {
Ok(HttpResponse::PermanentRedirect() Ok(HttpResponse::PermanentRedirect()
@ -159,10 +180,7 @@ fn show_answer(data: web::Data<AppState>, id: web::Path<u32>) -> Result<HttpResp
} }
fn index(data: web::Data<AppState>, _req: HttpRequest) -> Result<HttpResponse, Error> { fn index(data: web::Data<AppState>, _req: HttpRequest) -> Result<HttpResponse, Error> {
let collection = data.storage.collection("questions").expect("collection questions"); let id = random_question_id(&data.database_distribution);
let mut rng = rand::thread_rng();
let last_id = collection.last_id().expect("questions last id");
let id = (1..=last_id).choose(&mut rng).expect("random id");
let url = format!("/q/{}", id); let url = format!("/q/{}", id);
@ -184,10 +202,14 @@ fn main() {
let storage = Storage::new("db", options).expect("db open"); let storage = Storage::new("db", options).expect("db open");
HttpServer::new(move || { HttpServer::new(move || {
let data = AppState { let mut data = AppState {
storage: storage.clone(), storage: storage.clone(),
template: compile_templates!("./templates/**/*"), template: compile_templates!("./templates/**/*"),
database_distribution: Uniform::new(1, 3),
}; };
data.database_distribution = get_database_distribution(&data.storage);
let data = data;
App::new() App::new()
.wrap(Logger::default()) .wrap(Logger::default())
.data(data) .data(data)