Easier query, args

This commit is contained in:
Simon Cambier 2024-12-29 23:59:49 +01:00
parent fd9b7d0370
commit e6112df427
4 changed files with 78 additions and 20 deletions

41
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "actix-codec" name = "actix-codec"
@ -243,6 +243,38 @@ version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "argh"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240"
dependencies = [
"argh_derive",
"argh_shared",
"rust-fuzzy-search",
]
[[package]]
name = "argh_derive"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803"
dependencies = [
"argh_shared",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "argh_shared"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
@ -1046,12 +1078,19 @@ dependencies = [
"walkdir", "walkdir",
] ]
[[package]]
name = "rust-fuzzy-search"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2"
[[package]] [[package]]
name = "rust-name-gen" name = "rust-name-gen"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-web", "actix-web",
"anyhow", "anyhow",
"argh",
"rand", "rand",
"rust-embed", "rust-embed",
"serde", "serde",

View File

@ -6,6 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
actix-web = "4" actix-web = "4"
anyhow = "1.0.95" anyhow = "1.0.95"
argh = "0.1.13"
rand = "0.8.5" rand = "0.8.5"
rust-embed = "8.5.0" rust-embed = "8.5.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View File

@ -5,15 +5,12 @@ meta {
} }
get { get {
url: 127.0.0.1:8080 url: 127.0.0.1:8080?gender=f&dictionaries=prenom patronyme article commun adjectif
body: json body: json
auth: none auth: none
} }
body:json { params:query {
{ gender: f
"qty": 50, dictionaries: prenom patronyme article commun adjectif
"gender": "f",
"dictionaries": ["prenom", "patronyme", "virgule", "article", "commun", "adjectif", "ppasse", "ppresent"]
}
} }

View File

@ -1,43 +1,60 @@
use std::{collections::HashMap, str::from_utf8}; use std::{collections::HashMap, str::from_utf8, vec};
use actix_web::{get, web, App, HttpResponse, HttpServer}; use actix_web::{get, web, App, HttpResponse, HttpServer};
use argh::FromArgs;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use rust_embed::Embed; use rust_embed::Embed;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
static ARTICLE: &str = "<article>"; static ARTICLE: &str = "<article>";
#[derive(FromArgs)]
#[argh(description = "arguments")]
struct Args {
#[argh(option, short = 'h', description = "host")]
host: Option<String>,
#[argh(option, short = 'p', description = "port")]
port: Option<u16>,
}
#[derive(Embed)] #[derive(Embed)]
#[folder = "dictionaries/"] #[folder = "dictionaries/"]
struct Dictionaries; struct Dictionaries;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct NameGenQuery { struct NameGenQuery {
dictionaries: Vec<String>, dictionaries: Option<String>,
gender: String, gender: Option<String>,
qty: Option<u8>, qty: Option<u8>,
} }
#[get("/")] #[get("/")]
async fn index(query: web::Json<NameGenQuery>) -> HttpResponse { async fn index(query: web::Query<NameGenQuery>) -> HttpResponse {
// Load the dictionaries into memory // Load the dictionaries into memory
let mut dictionaries = HashMap::new(); let mut dictionaries = HashMap::new();
for filename in Dictionaries::iter() { for filename in Dictionaries::iter() {
if let Some(file) = Dictionaries::get(&filename) { if let Some(file) = Dictionaries::get(&filename) {
let data = from_utf8(file.data.as_ref()).unwrap(); let data = from_utf8(file.data.as_ref()).unwrap();
dictionaries.insert(filename.to_string(), serde_json::from_str::<Vec<String>>(data).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 qty = query.0.qty.unwrap_or(10).min(50).max(1);
let gender = match query.0.gender.as_str() { let gender = match query.0.gender.unwrap_or("m".to_string()).as_str() {
"m" => "masculins", "m" => "masculins",
"f" => "feminins", "f" => "feminins",
_ => "masculins", _ => "masculins",
}; };
// Limit to 10 parts max // Limit to 10 parts max
let mut chosen_dicts = query.0.dictionaries; let q_dicts = query
.0
.dictionaries
.unwrap_or("prenom patronyme".to_string());
let mut chosen_dicts = q_dicts.split(" ").collect::<Vec<_>>();
chosen_dicts.truncate(10); chosen_dicts.truncate(10);
let mut names = vec![]; let mut names = vec![];
@ -46,7 +63,7 @@ async fn index(query: web::Json<NameGenQuery>) -> HttpResponse {
let mut parts = vec![]; let mut parts = vec![];
for dict in chosen_dicts.iter() { for dict in chosen_dicts.iter() {
let filename = match dict.as_str() { let filename = match *dict {
"adjectif" | "commun" | "ppasse" | "ppresent" | "prenom" => { "adjectif" | "commun" | "ppasse" | "ppresent" | "prenom" => {
Some(format!("{dict}s_{gender}.json")) Some(format!("{dict}s_{gender}.json"))
} }
@ -71,9 +88,9 @@ async fn index(query: web::Json<NameGenQuery>) -> HttpResponse {
if item == ARTICLE { if item == ARTICLE {
// Check the next word // Check the next word
if let Some(next) = parts.get(i + 1) { if let Some(next) = parts.get(i + 1) {
if next if next.starts_with(|c| {
.starts_with(|c| vec!['a', 'e', 'i', 'o', 'u', 'é', 'è', 'ê', 'h'].contains(&c)) vec!['a', 'e', 'i', 'o', 'u', 'é', 'è', 'ê', 'h'].contains(&c)
{ }) {
to_replace.push((i, "l'")); to_replace.push((i, "l'"));
} else { } else {
to_replace.push((i, (if gender == "masculins" { "le" } else { "la" }))) to_replace.push((i, (if gender == "masculins" { "le" } else { "la" })))
@ -100,8 +117,12 @@ async fn index(query: web::Json<NameGenQuery>) -> HttpResponse {
#[actix_web::main] // or #[tokio::main] #[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let args: Args = argh::from_env();
let host = args.host.unwrap_or("127.0.0.1".to_string());
let port = args.port.unwrap_or(8080);
HttpServer::new(|| App::new().service(index)) HttpServer::new(|| App::new().service(index))
.bind(("127.0.0.1", 8080))? .bind((host, port))?
.run() .run()
.await .await
} }