use std::{collections::HashMap, str::from_utf8}; use actix_web::{get, web, App, HttpResponse, HttpServer}; use rand::seq::SliceRandom; use rust_embed::Embed; use serde::{Deserialize, Serialize}; static ARTICLE: &str = "
"; #[derive(Embed)] #[folder = "dictionaries/"] struct Dictionaries; #[derive(Debug, Serialize, Deserialize)] struct NameGenQuery { dictionaries: Vec, gender: String, qty: Option, } #[get("/")] async fn index(query: web::Json) -> HttpResponse { // Load the dictionaries into memory let mut dictionaries = HashMap::new(); for filename in Dictionaries::iter() { if let Some(file) = Dictionaries::get(&filename) { let data = from_utf8(file.data.as_ref()).unwrap(); dictionaries.insert(filename.to_string(), serde_json::from_str::>(data).unwrap()); } } let qty = query.0.qty.unwrap_or(10).min(50).max(1); let gender = match query.0.gender.as_str() { "m" => "masculins", "f" => "feminins", _ => "masculins", }; // Limit to 10 parts max let mut chosen_dicts = query.0.dictionaries; chosen_dicts.truncate(10); let mut names = vec![]; for _ in 0..qty { let mut parts = vec![]; for dict in chosen_dicts.iter() { let filename = match dict.as_str() { "adjectif" | "commun" | "ppasse" | "ppresent" | "prenom" => { Some(format!("{dict}s_{gender}.json")) } "patronyme" => Some(format!("{dict}s.json")), "article" => Some(ARTICLE.to_string()), "virgule" => Some(",".to_string()), _ => None, }; if let Some(filename) = filename { if let Some(data) = dictionaries.get(&filename) { let item = data.choose(&mut rand::thread_rng()).unwrap(); parts.push(item.to_string()) } else { parts.push(filename) } } } // Replace the
with le/la/l' let mut to_replace = vec![]; for (i, item) in parts.iter().enumerate() { if item == ARTICLE { // Check the next word if let Some(next) = parts.get(i + 1) { if next .starts_with(|c| vec!['a', 'e', 'i', 'o', 'u', 'é', 'è', 'ê', 'h'].contains(&c)) { to_replace.push((i, "l'")); } else { to_replace.push((i, (if gender == "masculins" { "le" } else { "la" }))) } } } } for item in to_replace.iter() { parts[item.0] = item.1.to_string(); } let joined = parts .join(" ") // Remove space after "l'" .replace("l' ", "l'") // Remove space before comma .replace(" ,", ","); names.push(joined); } HttpResponse::Ok().json(names) } #[actix_web::main] // or #[tokio::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new().service(index)) .bind(("127.0.0.1", 8080))? .run() .await }