forked from Roflin/gamenight
Adds renaming games functionality
This commit is contained in:
68
gamenight-cli/Cargo.lock
generated
68
gamenight-cli/Cargo.lock
generated
@@ -45,9 +45,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
@@ -84,9 +84,9 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.18.1"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -102,9 +102,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.26"
|
||||
version = "1.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
|
||||
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@@ -381,9 +381,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.14"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
|
||||
checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -552,6 +552,17 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
@@ -601,9 +612,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
@@ -825,24 +836,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.20"
|
||||
version = "0.12.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
|
||||
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -1013,6 +1024,12 @@ dependencies = [
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
@@ -1037,9 +1054,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.102"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1088,12 +1105,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1139,17 +1155,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.45.1"
|
||||
version = "1.46.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
||||
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"mio 1.0.4",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
@@ -1459,9 +1477,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
|
||||
26
gamenight-cli/src/domain/game.rs
Normal file
26
gamenight-cli/src/domain/game.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use gamenight_api_client_rs::models;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Game {
|
||||
pub id: Uuid,
|
||||
pub name: String
|
||||
}
|
||||
|
||||
impl From<models::Game> for Game {
|
||||
fn from(game: models::Game) -> Self {
|
||||
Self {
|
||||
id: Uuid::parse_str(&game.id).unwrap(),
|
||||
name: game.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Game {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Name: {}", self.name)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod gamenight;
|
||||
pub mod user;
|
||||
pub mod config;
|
||||
pub mod participants;
|
||||
pub mod participants;
|
||||
pub mod game;
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::game_post, models::{AddGameRequestBody, Game}};
|
||||
use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody};
|
||||
use inquire::{Confirm, Text};
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
use gamenight_api_client_rs::models::Game;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EditGame {
|
||||
game: Game
|
||||
}
|
||||
|
||||
impl EditGame {
|
||||
pub fn new(game: Game) -> Self {
|
||||
Self {
|
||||
game
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for EditGame {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for EditGame {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,7 @@ impl<'a> Flow<'a> for GamenightMenu {
|
||||
})
|
||||
.prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,8 @@ impl<'a> Flow<'a> for Games {
|
||||
..Default::default()
|
||||
})
|
||||
.prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ impl<'a> Flow<'a> for ListGamenights {
|
||||
|
||||
let choice = Select::new("What gamenight would you like to view?", view_flows).prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::apis::default_api::games_get;
|
||||
use inquire::{ui::RenderConfig, Select};
|
||||
|
||||
use crate::flows::{edit_game::EditGame, exit::Exit};
|
||||
use crate::flows::{view_game::ViewGame, exit::Exit};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -25,7 +25,7 @@ impl<'a> Flow<'a> for ListGames {
|
||||
let games = games_get(&state.api_configuration).await?;
|
||||
|
||||
let mut flows = games.into_iter().map(|game| -> Box<dyn Flow + Send> {
|
||||
Box::new(EditGame::new(game))
|
||||
Box::new(ViewGame::new(game.into()))
|
||||
}).collect::<Vec::<Box::<dyn Flow + Send>>>();
|
||||
|
||||
flows.push(Box::new(Exit::new()));
|
||||
@@ -38,9 +38,7 @@ impl<'a> Flow<'a> for ListGames {
|
||||
})
|
||||
.prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,7 @@ impl<'a> Flow<'a> for Main {
|
||||
})
|
||||
.prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ mod settings;
|
||||
mod games;
|
||||
mod list_games;
|
||||
mod add_game;
|
||||
mod edit_game;
|
||||
mod view_game;
|
||||
mod rename_game;
|
||||
|
||||
pub struct GamenightState {
|
||||
api_configuration: Configuration,
|
||||
@@ -111,25 +112,27 @@ dyn_clone::clone_trait_object!(for<'a> Flow<'a>);
|
||||
|
||||
#[async_trait]
|
||||
pub trait Flow<'a>: Sync + DynClone + Send + Display {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a>;
|
||||
}
|
||||
|
||||
async fn handle_choice<'a>(choice: &Box<dyn Flow<'a> + Send>, flow: &dyn Flow<'a>, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let (outcome, new_state) = choice.run(state).await?;
|
||||
async fn continue_choice(&self, state: &'a mut GamenightState, choice: &Option<Box<dyn Flow<'a> + Send>>) -> FlowResult<'a> {
|
||||
clear_screen::clear();
|
||||
if let Some(choice) = choice {
|
||||
let (outcome, new_state) = choice.run(state).await?;
|
||||
|
||||
if outcome == FlowOutcome::Abort {
|
||||
Ok((FlowOutcome::Successful, new_state))
|
||||
if outcome == FlowOutcome::Abort {
|
||||
Ok((FlowOutcome::Successful, new_state))
|
||||
}
|
||||
else {
|
||||
self.run(new_state).await
|
||||
}
|
||||
}
|
||||
else {
|
||||
Ok((FlowOutcome::Cancelled, state))
|
||||
}
|
||||
}
|
||||
else {
|
||||
flow.run(new_state).await
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_choice_option<'a>(choice: &Option<Box<dyn Flow<'a> + Send>>, flow: &dyn Flow<'a>, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
if let Some(choice) = choice {
|
||||
handle_choice(choice, flow, state).await
|
||||
}
|
||||
else {
|
||||
Ok((FlowOutcome::Cancelled, state))
|
||||
|
||||
async fn continue_with(&self, state: &'a mut GamenightState, other: &dyn Flow<'a>) -> FlowResult<'a> {
|
||||
clear_screen::clear();
|
||||
other.run(state).await
|
||||
}
|
||||
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a>;
|
||||
}
|
||||
47
gamenight-cli/src/flows/rename_game.rs
Normal file
47
gamenight-cli/src/flows/rename_game.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::rename_game_post, models::RenameGameRequestBody};
|
||||
use inquire::Text;
|
||||
|
||||
use crate::domain::game::Game;
|
||||
|
||||
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RenameGame {
|
||||
pub game: Game
|
||||
}
|
||||
|
||||
impl RenameGame {
|
||||
pub fn new(game: Game) -> Self {
|
||||
Self{
|
||||
game
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for RenameGame {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
if let Some(name) = Text::new(&format!("Rename {} to:", self.game.name))
|
||||
.with_initial_value(&format!("{}", self.game.name))
|
||||
.prompt_skippable()?
|
||||
{
|
||||
let req = RenameGameRequestBody {
|
||||
id: self.game.id.to_string(),
|
||||
name
|
||||
};
|
||||
rename_game_post(&state.api_configuration, Some(req)).await?;
|
||||
|
||||
return Ok((FlowOutcome::Successful, state))
|
||||
}
|
||||
Ok((FlowOutcome::Cancelled, state))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RenameGame {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Rename")
|
||||
}
|
||||
}
|
||||
46
gamenight-cli/src/flows/view_game.rs
Normal file
46
gamenight-cli/src/flows/view_game.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
use gamenight_api_client_rs::{apis::default_api::game_get, models::GameId};
|
||||
use inquire::Select;
|
||||
|
||||
use crate::{domain::game::Game, flows::{exit::Exit, rename_game::RenameGame}};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ViewGame {
|
||||
game: Game
|
||||
}
|
||||
|
||||
impl ViewGame {
|
||||
pub fn new(game: Game) -> Self {
|
||||
Self {
|
||||
game
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for ViewGame {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let game_id = GameId{ game_id: self.game.id.to_string() };
|
||||
let game: Game = game_get(&state.api_configuration, Some(game_id)).await?.into();
|
||||
|
||||
println!("{}", game);
|
||||
|
||||
let options: Vec<Box<dyn Flow<'a> + Send>> = vec![
|
||||
Box::new(RenameGame::new(game.clone())),
|
||||
Box::new(Exit::new())
|
||||
];
|
||||
let choice = Select::new("What do you want to do:", options)
|
||||
.prompt_skippable()?;
|
||||
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ViewGame {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", &self.game.name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ impl<'a> Flow<'a> for ViewGamenight {
|
||||
let choice = Select::new("What do you want to do:", options)
|
||||
.prompt_skippable()?;
|
||||
|
||||
clear_screen::clear();
|
||||
handle_choice_option(&choice, self, state).await
|
||||
self.continue_choice(state, &choice).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user