simple CLI app

This commit is contained in:
Simon Cambier 2024-12-30 17:35:44 +01:00
parent 1088b94577
commit 9421d61b91
4 changed files with 37 additions and 1252 deletions

1194
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,6 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
actix-web = "4"
anyhow = "1.0.95"
argh = "0.1.13" argh = "0.1.13"
rand = "0.8.5" rand = "0.8.5"
rust-embed = "8.5.0" rust-embed = "8.5.0"

View File

@ -2,24 +2,31 @@
## Utilisation ## Utilisation
Les deux arguments sont facultatifs
```sh ```sh
./rust-name-gen --host 127.0.0.1 --port 8080 ./rust-name-gen --sequence "prenom patronyme"
``` ```
### Query params pour générer les noms ### Pendant le developpement
- `qty` - Nombre de noms générés, entre `1` et `50`. Défaut `10`. ```sh
- `sep` - Le caractère de séparation entre les sections des noms générés. Utilise l'espace par défaut. cargo run -- --sequence "prenom patronyme"
- `gender` - Genre des noms générés, `m` ou `f`. Défaut au hasard. ```
- `sequence` - Une suite de mots-clés pour déterminer la structure du nom, séparés par un espace. Valeurs acceptés : `prenom patronyme commun adjectif ppasse ppresent article virgule`
### Arguments
Tous les arguments sont facultatifs
- `--qty` - Nombre de noms générés, entre `1` et `50`. Défaut `10`.
- `--sep` - Le caractère de séparation entre les sections des noms générés. Utilise l'espace par défaut.
- `--gender` - Genre des noms générés, `m` ou `f`. Défaut au hasard.
- `--sequence` - Une suite de mots-clés pour déterminer la structure du nom, séparés par un espace. Valeurs acceptés : `prenom patronyme commun adjectif ppasse ppresent article virgule`. Défaut `prenom patronyme`
- `ppasse`/`ppresent` pour "participe passé/présent". - `ppasse`/`ppresent` pour "participe passé/présent".
- `article` sera transformé en `le`/`la`/`l'`. - `article` sera transformé en `le`/`la`/`l'`.
- `virgule` est... une virgule. - `virgule` est... une virgule.
Exemple : Exemple :
```http ```http
GET 127.0.0.1:8080?qty=5&sequence=prenom%20patronyme%20virgule%20article%20commun%20adjectif%20ppresent%20ppasse ./rust-name-gen --qty 5 --sequence "prenom patronyme virgule article commun adjectif ppresent ppasse"
``` ```
Résultat : Résultat :
@ -33,12 +40,6 @@ Résultat :
] ]
``` ```
## Live reload
```
cargo watch -x run
```
## Build de production ## Build de production
``` ```

View File

@ -1,10 +1,8 @@
use std::{collections::HashMap, str::from_utf8, vec}; use std::{collections::HashMap, str::from_utf8, vec};
use actix_web::{get, web, App, HttpResponse, HttpServer};
use argh::FromArgs; use argh::FromArgs;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use rust_embed::Embed; use rust_embed::Embed;
use serde::{Deserialize, Serialize};
static ARTICLE: &str = "<article>"; static ARTICLE: &str = "<article>";
static GENDER_M: &str = "masculins"; static GENDER_M: &str = "masculins";
@ -13,27 +11,22 @@ static RANDOM: &str = "random";
#[derive(FromArgs)] #[derive(FromArgs)]
#[argh(description = "arguments")] #[argh(description = "arguments")]
struct Args { struct Arguments {
#[argh(option, short = 'h', description = "host")] #[argh(option, description = "nombre de noms à générer")]
host: Option<String>, qty: Option<u8>,
#[argh(option, short = 'p', description = "port")] #[argh(option, description = "separateur")]
port: Option<u16>, sep: Option<String>,
#[argh(option, description = "gender")]
gender: Option<String>,
#[argh(option, description = "sequence")]
sequence: Option<String>,
} }
#[derive(Embed)] #[derive(Embed)]
#[folder = "dictionaries/"] #[folder = "dictionaries/"]
struct Dictionaries; struct Dictionaries;
#[derive(Debug, Serialize, Deserialize)] fn main() {
struct NameGenQuery {
sequence: Option<String>,
gender: Option<String>,
qty: Option<u8>,
sep: Option<String>,
}
#[get("/")]
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() {
@ -46,16 +39,17 @@ async fn index(query: web::Query<NameGenQuery>) -> HttpResponse {
} }
} }
let qty = query.0.qty.unwrap_or(10).min(50).max(1); let args: Arguments = argh::from_env();
let sep = query.0.sep.unwrap_or(" ".to_string()); let qty = args.qty.unwrap_or(10).min(50).max(1);
let gender = match query.0.gender.as_ref().map(String::as_ref) { let sep = args.sep.unwrap_or(" ".to_string());
let gender = match args.gender.as_ref().map(String::as_ref) {
Some("m") => GENDER_M, Some("m") => GENDER_M,
Some("f") => GENDER_F, Some("f") => GENDER_F,
_ => RANDOM, _ => RANDOM,
}; };
// Limit to 10 parts max // Limit to 10 parts max
let q_dicts = query.0.sequence.unwrap_or("prenom patronyme".to_string()); let q_dicts = args.sequence.unwrap_or("prenom patronyme".to_string());
let mut chosen_dicts = q_dicts.split(" ").collect::<Vec<_>>(); let mut chosen_dicts = q_dicts.split(" ").collect::<Vec<_>>();
chosen_dicts.truncate(10); chosen_dicts.truncate(10);
@ -71,7 +65,6 @@ async fn index(query: web::Query<NameGenQuery>) -> HttpResponse {
} else { } else {
gender gender
}; };
println!("{gender}");
for dict in chosen_dicts.iter() { for dict in chosen_dicts.iter() {
let filename = match *dict { let filename = match *dict {
@ -122,18 +115,5 @@ async fn index(query: web::Query<NameGenQuery>) -> HttpResponse {
names.push(joined); names.push(joined);
} }
println!("{}", serde_json::to_string(&names).unwrap());
HttpResponse::Ok().json(names)
}
#[actix_web::main] // or #[tokio::main]
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))
.bind((host, port))?
.run()
.await
} }