First commit
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
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 = "<article>";
|
||||
|
||||
#[derive(Embed)]
|
||||
#[folder = "dictionaries/"]
|
||||
struct Dictionaries;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct NameGenQuery {
|
||||
dictionaries: Vec<String>,
|
||||
gender: String,
|
||||
qty: Option<u8>,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn index(query: web::Json<NameGenQuery>) -> 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::<Vec<String>>(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 <article> 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
|
||||
}
|
||||
Reference in New Issue
Block a user