First commit

This commit is contained in:
Simon Cambier 2024-12-29 21:12:39 +01:00
commit 30531311bb
22 changed files with 227544 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/rust-name-gen.iml" filepath="$PROJECT_DIR$/.idea/rust-name-gen.iml" />
</modules>
</component>
</project>

11
.idea/rust-name-gen.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

1593
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

12
Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "rust-name-gen"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
anyhow = "1.0.95"
rand = "0.8.5"
rust-embed = "8.5.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

1
README.md Normal file
View File

@ -0,0 +1 @@
cargo watch -x run

9
bruno/NameGen/bruno.json Normal file
View File

@ -0,0 +1,9 @@
{
"version": "1",
"name": "NameGen",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}

19
bruno/NameGen/index.bru Normal file
View File

@ -0,0 +1,19 @@
meta {
name: index
type: http
seq: 2
}
get {
url: 127.0.0.1:8080
body: json
auth: none
}
body:json {
{
"qty": 50,
"gender": "f",
"dictionaries": ["prenom", "patronyme", "virgule", "article", "commun", "adjectif", "ppasse", "ppresent"]
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

61958
dictionaries/patronymes.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,285 @@
[
"Adélaïde",
"Adèle",
"Adeline",
"Adrienne",
"Agathe",
"Agnès",
"Aimée",
"Albertine",
"Alexandrie",
"Aline",
"Alphonsine",
"Amarante",
"Ambre",
"Amélie",
"Anastasie",
"Andrée",
"Angèle",
"Angeline",
"Angelique",
"Anne",
"Annette",
"Antoinette",
"Apolline",
"Arianne",
"Arienne",
"Arlette",
"Armelle",
"Arnaude",
"Aude",
"Aurélie",
"Aurore",
"Avril",
"Axelle",
"Béatrice",
"Bénédicte",
"Benjamine",
"Benoite",
"Bernadette",
"Berthe",
"Blanche",
"Camille",
"Carine",
"Carole",
"Caroline",
"Cécile",
"Céleste",
"Célestine",
"Céline",
"Cerise",
"Chantal",
"Chanté",
"Charline",
"Charlotte",
"Chloé",
"Christelle",
"Christine",
"Claire",
"Clarisse",
"Claude",
"Claudette",
"Claudine",
"Clémence",
"Clementine",
"Clothilde",
"Colette",
"Colombe",
"Corinne",
"Cosette",
"Cunégonde",
"Cyrille",
"Danièle",
"Danielle",
"Delphine",
"Denise",
"Désirée",
"Diane",
"Dianne",
"Dieudonnée",
"Dominique",
"Donatienne",
"Doriane",
"Dorothée",
"Édith",
"Edwige",
"Eléonore",
"Éliane",
"Élise",
"Élodie",
"Éloise",
"Emeline",
"Émilie",
"Emmanuelle",
"Esmé",
"Esmée",
"Eugénie",
"Eulalie",
"Evette",
"Fabienne",
"Faustine",
"Félicie",
"Felicienne",
"Fernande",
"Fifi",
"Flavie",
"Florette",
"Florianne",
"Francine",
"Françoise",
"Frédérique",
"Gabrielle",
"Gaetane",
"Geneviève",
"Georgette",
"Georgine",
"Germaine",
"Gervaise",
"Ghislaine",
"Gigi",
"Gilberte",
"Gisèle",
"Giselle",
"Gisselle",
"Gwenaelle",
"Hélène",
"Héloïse",
"Henriette",
"Honorine",
"Hortense",
"Hyacinthe",
"Inès",
"Irène",
"Irénée",
"Jacinthe",
"Jacqueline",
"Jeanine",
"Jeanne",
"Jeannette",
"Jeannine",
"Joceline",
"Joelle",
"Jolie",
"Josée",
"Josèphe",
"Joséphine",
"Josette",
"Josiane",
"Juliane",
"Julie",
"Julienne",
"Juliette",
"Justine",
"Laure",
"Laurence",
"Laurentine",
"Laurette",
"Léa",
"Léonie",
"Léonne",
"Léontine",
"Liane",
"Lisette",
"Louise",
"Luce",
"Lucie",
"Lucienne",
"Lucile",
"Lucille",
"Lucinde",
"Lucrece",
"Lunete",
"Lydie",
"Madeleine",
"Madeline",
"Manon",
"Marceline",
"Marcelle",
"Marcellette",
"Marcelline",
"Margot",
"Marguerite",
"Marianne",
"Marie",
"Marielle",
"Mariette",
"Marine",
"Marise",
"Marthe",
"Martine",
"Mathilde",
"Maximilienne",
"Mélanie",
"Mélissa",
"Michèle",
"Micheline",
"Michelle",
"Mignon",
"Mirabelle",
"Mireille",
"Monique",
"Morgaine",
"Morgane",
"Myriam",
"Nadia",
"Nadine",
"Natalie",
"Nathalie",
"Nicole",
"Nicolette",
"Ninette",
"Ninon",
"Noella",
"Noelle",
"Noémie",
"Océane",
"Odette",
"Odile",
"Olivie",
"Olympe",
"Oriane",
"Orianne",
"Osanne",
"Ouida",
"Ozanne",
"Pascale",
"Pascaline",
"Paule",
"Paulette",
"Pauline",
"Pénélope",
"Perrine",
"Philippine",
"Placide",
"Raymonde",
"Rébecca",
"Régine",
"Reine",
"Renée",
"Rochelle",
"Rolande",
"Romaine",
"Rosalie",
"Roselle",
"Rosemonde",
"Rosette",
"Rosine",
"Roxane",
"Sabine",
"Sacha",
"Salomé",
"Sandrine",
"Sébastienne",
"Seraphine",
"Sévérine",
"Sidonie",
"Simone",
"Solange",
"Sophie",
"Stéphanie",
"Suzanne",
"Suzette",
"Sylvaine",
"Sylviane",
"Sylvianne",
"Sylvie",
"Tatienne",
"Thérèse",
"Toinette",
"Valentine",
"Valérie",
"Véronique",
"Victoire",
"Victorine",
"Vienne",
"Violette",
"Virginie",
"Vivien",
"Vivienne",
"Yolande",
"Yseult",
"Yvette",
"Yvonne",
"Zephyrine",
"Zoé"
]

View File

@ -0,0 +1,204 @@
[
"Absolon",
"Achille",
"Adolphe",
"Adrien",
"Aimé",
"Alain",
"Alexandre",
"Alphonse",
"Amaury",
"Ambroise",
"Amédée",
"Anatole",
"André",
"Anselme",
"Antoine",
"Apollinaire",
"Aristide",
"Armand",
"Armel",
"Arnaud",
"Auguste",
"Augustin",
"Aurèle",
"Aurelien",
"Baptiste",
"Barnabé",
"Barthélémy",
"Basile",
"Bastien",
"Baudouin",
"Benoit",
"Bertrand",
"Blaise",
"Brice",
"Camille",
"Célestin",
"Cesaire",
"César",
"Charlot",
"Christophe",
"Claude",
"Clément",
"Colombain",
"Colombe",
"Constantin",
"Corin",
"Cyrille",
"Damien",
"Denis",
"Désiré",
"Didier",
"Dieudonné",
"Diodore",
"Dion",
"Dominique",
"Donat",
"Donatien",
"Edgard",
"Edmond",
"Édouard",
"Eloi",
"Émile",
"Émilien",
"Ermenegilde",
"Esmé",
"Étienne",
"Eugène",
"Eustache",
"Évariste",
"Evrard",
"Fabien",
"Fabrice",
"Felicien",
"Félix",
"Fernand",
"Fiacre",
"Firmin",
"Florentin",
"Franck",
"François",
"Frédéric",
"Gaétan",
"Gaspard",
"Gaston",
"Gautier",
"Geoffroi",
"Georges",
"Gérald",
"Gérard",
"Géraud",
"Germain",
"Gervais",
"Ghislain",
"Gilles",
"Godelieve",
"Gratien",
"Grégoire",
"Guillaume",
"Gustave",
"Henri",
"Hercule",
"Hervé",
"Hilaire",
"Honoré",
"Hugues",
"Ignace",
"Iréné",
"Jacques",
"Jean",
"Jean-Baptiste",
"Jean-Marie",
"Jean-Pierre",
"Jeannot",
"Jérémie",
"Jérôme",
"Joël",
"Jourdain",
"Jules",
"Julien",
"Juste",
"Laurent",
"Lazare",
"Léandre",
"Léon",
"Léonard",
"Léonce",
"Léopold",
"Lionel",
"Loic",
"Lothaire",
"Louis",
"Loup",
"Luc",
"Lucien",
"Marc",
"Marcel",
"Marcellin",
"Marin",
"Mathieu",
"Matthieu",
"Maxime",
"Maximilien",
"Michel",
"Modeste",
"Modestine",
"Narcisse",
"Nazaire",
"Nicodème",
"Nicolas",
"Noé",
"Noel",
"Olivier",
"Onesime",
"Osanne",
"Ozanne",
"Papillion",
"Pascal",
"Paschal",
"Patrice",
"Perceval",
"Philibert",
"Philippe",
"Pierre",
"Pons",
"Prosper",
"Rainier",
"Raoul",
"Raphaël",
"Régis",
"Rémi",
"Rémy",
"Renard",
"Renaud",
"René",
"Reynaud",
"Roch",
"Rodolphe",
"Rodrigue",
"Romain",
"Sacha",
"Sébastien",
"Serge",
"Séverin",
"Stéphane",
"Sylvain",
"Sylvestre",
"Telesphore",
"Theirn",
"Théo",
"Théodore",
"Théophile",
"Thibault",
"Thierry",
"Timothée",
"Toussaint",
"Urbain",
"Valère",
"Valéry",
"Vespasien",
"Vivien",
"Yves",
"Zacharie"
]

107
src/main.rs Normal file
View File

@ -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
}