Rewrite to a API trait.
This commit is contained in:
16
backend-actix/Cargo.lock
generated
16
backend-actix/Cargo.lock
generated
@@ -1243,9 +1243,9 @@ checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.1"
|
||||
version = "2.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@@ -2175,9 +2175,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.113"
|
||||
version = "2.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2781,18 +2781,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.31"
|
||||
version = "0.8.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
|
||||
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.31"
|
||||
version = "0.8.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -337,6 +337,8 @@ components:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
location_id:
|
||||
type: string
|
||||
datetime:
|
||||
type: string
|
||||
owner_id:
|
||||
@@ -408,6 +410,16 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- user_id
|
||||
OwnedGame:
|
||||
title: OwnedGame
|
||||
type: object
|
||||
properties:
|
||||
game_id:
|
||||
type: string
|
||||
location_id:
|
||||
type: string
|
||||
required:
|
||||
- game_id
|
||||
LocationId:
|
||||
title: LocationId
|
||||
type: object
|
||||
@@ -499,7 +511,7 @@ components:
|
||||
GameIdsResponse:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
$ref: "#/components/schemas/OwnedGame"
|
||||
UserIdsResponse:
|
||||
type: array
|
||||
items:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use gamenight_database::owned_game::OwnedGame;
|
||||
use crate::game::rename_game;
|
||||
use crate::owned_game::own_game;
|
||||
use crate::owned_game::owned_games;
|
||||
use crate::owned_game::disown_game;
|
||||
use crate::owned_game::OwnedGame;
|
||||
use gamenight_database::game::load_game;
|
||||
use crate::game::insert_game;
|
||||
use uuid::Uuid;
|
||||
@@ -13,13 +13,10 @@ use gamenight_database::{
|
||||
DbPool, GetConnection,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
models::{
|
||||
add_game_request_body::AddGameRequestBody, game::Game, game_id::GameId,
|
||||
rename_game_request_body::RenameGameRequestBody, own_game_request_body::OwnGameRequestBody
|
||||
},
|
||||
request::{authorization::AuthUser, error::ApiError},
|
||||
};
|
||||
use crate::{models, models::{
|
||||
add_game_request_body::AddGameRequestBody, game::Game, game_id::GameId,
|
||||
rename_game_request_body::RenameGameRequestBody, own_game_request_body::OwnGameRequestBody
|
||||
}, request::{authorization::AuthUser, error::ApiError}};
|
||||
|
||||
#[get("/games")]
|
||||
pub async fn get_games(
|
||||
@@ -162,7 +159,11 @@ pub async fn get_owned_games(
|
||||
let mut conn = pool.get_conn();
|
||||
let game_ids = owned_games(&mut conn, user.0.id)?;
|
||||
|
||||
let model: Vec<String> = game_ids.iter().map(|x| x.to_string()).collect();
|
||||
|
||||
let model = game_ids.iter().map(|(u, l)| models::owned_game::OwnedGame {
|
||||
game_id: u.to_string(),
|
||||
location_id: l.map(|x| x.to_string())
|
||||
}).collect::<Vec<models::owned_game::OwnedGame>>();
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type(ContentType::json())
|
||||
|
||||
@@ -43,6 +43,7 @@ pub async fn gamenights(
|
||||
.map(|x| Gamenight {
|
||||
id: x.id.to_string(),
|
||||
name: x.name.clone(),
|
||||
location_id: x.location_id.map(|x| x.to_string()),
|
||||
datetime: x.datetime.to_rfc3339(),
|
||||
owner_id: x.owner_id.to_string(),
|
||||
})
|
||||
@@ -77,6 +78,7 @@ pub async fn gamenight_get(
|
||||
let model = Gamenight {
|
||||
id: gamenight.id.to_string(),
|
||||
datetime: gamenight.datetime.to_rfc3339(),
|
||||
location_id: gamenight.location_id.map(|x| x.to_string()),
|
||||
name: gamenight.name,
|
||||
owner_id: gamenight.owner_id.to_string(),
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ docs/Location.md
|
||||
docs/LocationId.md
|
||||
docs/Login.md
|
||||
docs/OwnGameRequestBody.md
|
||||
docs/OwnedGame.md
|
||||
docs/Participants.md
|
||||
docs/Registration.md
|
||||
docs/RenameGameRequestBody.md
|
||||
@@ -43,6 +44,7 @@ src/models/location_id.rs
|
||||
src/models/login.rs
|
||||
src/models/mod.rs
|
||||
src/models/own_game_request_body.rs
|
||||
src/models/owned_game.rs
|
||||
src/models/participants.rs
|
||||
src/models/registration.rs
|
||||
src/models/rename_game_request_body.rs
|
||||
|
||||
@@ -11,8 +11,8 @@ serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = "^1.0"
|
||||
serde_repr = "^0.1"
|
||||
url = "^2.5"
|
||||
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart"] }
|
||||
|
||||
async-trait = "^0.1"
|
||||
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart", "stream"] }
|
||||
[features]
|
||||
default = ["native-tls"]
|
||||
native-tls = ["reqwest/native-tls"]
|
||||
|
||||
@@ -69,6 +69,7 @@ Class | Method | HTTP request | Description
|
||||
- [LocationId](docs/LocationId.md)
|
||||
- [Login](docs/Login.md)
|
||||
- [OwnGameRequestBody](docs/OwnGameRequestBody.md)
|
||||
- [OwnedGame](docs/OwnedGame.md)
|
||||
- [Participants](docs/Participants.md)
|
||||
- [Registration](docs/Registration.md)
|
||||
- [RenameGameRequestBody](docs/RenameGameRequestBody.md)
|
||||
|
||||
@@ -4,7 +4,20 @@ fn main() {
|
||||
println!("cargo::rerun-if-changed=../backend-actix/gamenight-api.yaml");
|
||||
let _ =
|
||||
Command::new("openapi-generator")
|
||||
.args(["generate", "-i", "../backend-actix/gamenight-api.yaml", "-g", "rust", "--additional-properties=withSeparateModelsAndApi=true,modelPackage=gamenight_model,apiPackage=gamenight_api,packageName=gamenight-api-client-rs,packageVersion=0.1.0"])
|
||||
.args([
|
||||
"generate",
|
||||
"-i",
|
||||
"../backend-actix/gamenight-api.yaml",
|
||||
"-g",
|
||||
"rust",
|
||||
"--additional-properties=\
|
||||
withSeparateModelsAndApi=true,\
|
||||
library=reqwest-trait,\
|
||||
modelPackage=gamenight_model,\
|
||||
apiPackage=gamenight_api,\
|
||||
packageName=gamenight-api-client-rs,\
|
||||
packageVersion=0.1.0"
|
||||
])
|
||||
.output()
|
||||
.expect("Failed to generate models sources for the gamenight API");
|
||||
}
|
||||
@@ -476,7 +476,7 @@ Name | Type | Description | Required | Notes
|
||||
|
||||
## owned_games_get
|
||||
|
||||
> Vec<String> owned_games_get(user_id)
|
||||
> Vec<models::OwnedGame> owned_games_get(user_id)
|
||||
|
||||
|
||||
### Parameters
|
||||
@@ -488,7 +488,7 @@ Name | Type | Description | Required | Notes
|
||||
|
||||
### Return type
|
||||
|
||||
**Vec<String>**
|
||||
[**Vec<models::OwnedGame>**](OwnedGame.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **String** | |
|
||||
**name** | **String** | |
|
||||
**location_id** | Option<**String**> | | [optional]
|
||||
**datetime** | **String** | |
|
||||
**owner_id** | **String** | |
|
||||
|
||||
|
||||
12
gamenight-api-client-rs/docs/OwnedGame.md
Normal file
12
gamenight-api-client-rs/docs/OwnedGame.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# OwnedGame
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**game_id** | **String** | |
|
||||
**location_id** | Option<**String**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -114,3 +114,4 @@ impl From<&str> for ContentType {
|
||||
pub mod default_api;
|
||||
|
||||
pub mod configuration;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ extern crate serde_repr;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate url;
|
||||
extern crate reqwest;
|
||||
|
||||
pub mod apis;
|
||||
pub mod models;
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct Gamenight {
|
||||
pub id: String,
|
||||
#[serde(rename = "name")]
|
||||
pub name: String,
|
||||
#[serde(rename = "location_id", skip_serializing_if = "Option::is_none")]
|
||||
pub location_id: Option<String>,
|
||||
#[serde(rename = "datetime")]
|
||||
pub datetime: String,
|
||||
#[serde(rename = "owner_id")]
|
||||
@@ -28,6 +30,7 @@ impl Gamenight {
|
||||
Gamenight {
|
||||
id,
|
||||
name,
|
||||
location_id: None,
|
||||
datetime,
|
||||
owner_id,
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ pub mod login;
|
||||
pub use self::login::Login;
|
||||
pub mod own_game_request_body;
|
||||
pub use self::own_game_request_body::OwnGameRequestBody;
|
||||
pub mod owned_game;
|
||||
pub use self::owned_game::OwnedGame;
|
||||
pub mod participants;
|
||||
pub use self::participants::Participants;
|
||||
pub mod registration;
|
||||
|
||||
30
gamenight-api-client-rs/src/models/owned_game.rs
Normal file
30
gamenight-api-client-rs/src/models/owned_game.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Gamenight
|
||||
*
|
||||
* Api specification for a Gamenight server
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0
|
||||
* Contact: dennis@brentj.es
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct OwnedGame {
|
||||
#[serde(rename = "game_id")]
|
||||
pub game_id: String,
|
||||
#[serde(rename = "location_id", skip_serializing_if = "Option::is_none")]
|
||||
pub location_id: Option<String>,
|
||||
}
|
||||
|
||||
impl OwnedGame {
|
||||
pub fn new(game_id: String) -> OwnedGame {
|
||||
OwnedGame {
|
||||
game_id,
|
||||
location_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
72
gamenight-cli/Cargo.lock
generated
72
gamenight-cli/Cargo.lock
generated
@@ -108,6 +108,15 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@@ -221,21 +230,6 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
@@ -243,7 +237,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -252,17 +245,6 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
@@ -298,7 +280,6 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
@@ -332,6 +313,7 @@ dependencies = [
|
||||
name = "gamenight-api-client-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -346,8 +328,8 @@ dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"clear_screen",
|
||||
"colored",
|
||||
"dyn-clone",
|
||||
"futures",
|
||||
"gamenight-api-client-rs",
|
||||
"inquire",
|
||||
"jsonwebtoken",
|
||||
@@ -996,12 +978,14 @@ dependencies = [
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@@ -1236,9 +1220,9 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.113"
|
||||
version = "2.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1386,6 +1370,19 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.5.2"
|
||||
@@ -1604,6 +1601,19 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.83"
|
||||
|
||||
@@ -15,4 +15,4 @@ jsonwebtoken = "9.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
clear_screen = "0.1"
|
||||
futures = "0.3"
|
||||
colored = "3.0"
|
||||
|
||||
20
gamenight-cli/src/domain/eligable_games.rs
Normal file
20
gamenight-cli/src/domain/eligable_games.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use std::fmt::Display;
|
||||
use colored::Colorize;
|
||||
use crate::domain::location::Location;
|
||||
use crate::domain::owned_games::OwnedGames;
|
||||
|
||||
pub struct EligableGames<'a>(pub &'a OwnedGames, pub &'a Location);
|
||||
|
||||
impl Display for EligableGames<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for (k, v) in self.0.0.iter() {
|
||||
writeln!(f, "{}:", k)?;
|
||||
for (g, l) in v.iter() {
|
||||
if l.as_ref().is_none_or(|x| x.id == self.1.id) {
|
||||
writeln!(f, "\t{}", g.name.green())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use chrono::{DateTime, Local};
|
||||
use uuid::Uuid;
|
||||
use crate::domain::eligable_games::EligableGames;
|
||||
use crate::domain::location::Location;
|
||||
use crate::domain::owned_games::OwnedGames;
|
||||
use crate::domain::participants::Participants;
|
||||
use crate::domain::user::User;
|
||||
@@ -9,6 +11,7 @@ use crate::domain::user::User;
|
||||
pub struct Gamenight {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub location: Option<Location>,
|
||||
pub start_time: DateTime<Local>,
|
||||
pub organizer: User,
|
||||
pub participants: Participants,
|
||||
@@ -21,7 +24,12 @@ impl Display for Gamenight {
|
||||
writeln!(f, "Organizer: {}", self.organizer)?;
|
||||
writeln!(f, "Start: {}", self.start_time.to_rfc3339())?;
|
||||
writeln!(f, "Participants: {}", self.participants)?;
|
||||
write!(f, "Owned games:\n{}", self.owned_games)?;
|
||||
if let Some(location) = &self.location {
|
||||
write!(f, "Eligable games:\n{}", EligableGames(&self.owned_games, location))?;
|
||||
} else {
|
||||
write!(f, "Owned games: \n{}", self.owned_games)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use uuid::Uuid;
|
||||
pub struct GamenightSelectData {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub location_id: Option<Uuid>,
|
||||
pub start_time: DateTime<Local>,
|
||||
pub owner_id: Uuid,
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::fmt::Display;
|
||||
|
||||
use gamenight_api_client_rs::models;
|
||||
use uuid::Uuid;
|
||||
use crate::flows::FlowError;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Location {
|
||||
@@ -11,14 +12,15 @@ pub struct Location {
|
||||
pub note: Option<String>,
|
||||
}
|
||||
|
||||
impl From<models::Location> for Location {
|
||||
fn from(location: models::Location) -> Self {
|
||||
Self {
|
||||
id: Uuid::parse_str(&location.id).unwrap(),
|
||||
name: location.name,
|
||||
address: location.address,
|
||||
note: location.note
|
||||
}
|
||||
impl TryFrom<models::Location> for Location {
|
||||
type Error = FlowError;
|
||||
fn try_from(value: models::Location) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
id: Uuid::parse_str(&value.id)?,
|
||||
name: value.name,
|
||||
address: value.address,
|
||||
note: value.note
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,4 +6,5 @@ pub mod game;
|
||||
pub mod owned_games;
|
||||
pub mod location;
|
||||
pub mod location_select_data;
|
||||
pub mod gamenight;
|
||||
pub mod gamenight;
|
||||
mod eligable_games;
|
||||
@@ -1,15 +1,16 @@
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
|
||||
use crate::domain::game::Game;
|
||||
use crate::domain::location::Location;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OwnedGames(pub HashMap<String, Vec<Game>>);
|
||||
pub struct OwnedGames (pub HashMap<String, Vec<(Game, Option<Location>)>>);
|
||||
|
||||
impl Display for OwnedGames {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for (k,v) in &self.0 {
|
||||
write!(f, "{k}:\n")?;
|
||||
for g in v {
|
||||
for (g, _) in v {
|
||||
write!(f, "\t{}\n", g.name)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::fmt::Display;
|
||||
use super::*;
|
||||
use crate::flows::own::Own;
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody};
|
||||
use gamenight_api_client_rs::models::AddGameRequestBody;
|
||||
use inquire::Text;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<'a> Flow<'a> for AddGame {
|
||||
let add_game_request = AddGameRequestBody {
|
||||
name
|
||||
};
|
||||
let game_id_response = game_post(&state.api_configuration, Some(add_game_request)).await?;
|
||||
let game_id_response = state.api.game_post(Some(add_game_request)).await?;
|
||||
|
||||
let own_flow = Own::new(Uuid::parse_str(&game_id_response.game_id)?);
|
||||
return self.continue_with(state, &own_flow).await;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
use gamenight_api_client_rs::{apis::default_api::post_gamenight, models};
|
||||
use inquire::{CustomType, DateSelect, Text};
|
||||
use chrono::{self, Local, NaiveTime};
|
||||
|
||||
use gamenight_api_client_rs::models;
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -32,7 +31,7 @@ impl<'a> Flow<'a> for AddGamenight {
|
||||
.to_utc()
|
||||
.to_rfc3339();
|
||||
let add_gamenight = models::AddGamenightRequestBody::new(name, datetime);
|
||||
post_gamenight(&state.api_configuration, Some(add_gamenight)).await?;
|
||||
state.api.post_gamenight(Some(add_gamenight)).await?;
|
||||
|
||||
clear_screen::clear();
|
||||
return Ok((FlowOutcome::Successful, state))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{ffi::OsStr, fmt::Display};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::{location_authorize_post, location_post}, models::{authorize_location_request_body::Op::Grant, AddLocationRequestBody, AuthorizeLocationRequestBody}};
|
||||
use gamenight_api_client_rs::models::{authorize_location_request_body::Op::Grant, AddLocationRequestBody, AuthorizeLocationRequestBody};
|
||||
use inquire::{Editor, Text};
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ impl<'a> Flow<'a> for AddLocation {
|
||||
note
|
||||
};
|
||||
|
||||
let location_id = location_post(&state.api_configuration, Some(add_location_request)).await?;
|
||||
let location_id = state.api.location_post(Some(add_location_request)).await?;
|
||||
|
||||
let add_authorize_request = AuthorizeLocationRequestBody {
|
||||
location_id: location_id.location_id.to_string(),
|
||||
@@ -52,7 +52,7 @@ impl<'a> Flow<'a> for AddLocation {
|
||||
op: Grant
|
||||
};
|
||||
|
||||
location_authorize_post(&state.api_configuration, Some(add_authorize_request)).await?;
|
||||
state.api.location_authorize_post(Some(add_authorize_request)).await?;
|
||||
}
|
||||
Ok((FlowOutcome::Cancelled, state))
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::apis::configuration::Configuration;
|
||||
use inquire::Text;
|
||||
|
||||
use crate::{domain::config::{Config, Instance}, flows::{gamenight_menu::GamenightMenu, login::Login, FlowError}};
|
||||
|
||||
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
|
||||
use crate::{domain::config::{Config, Instance}, flows::{gamenight_menu::GamenightMenu, login::Login, FlowError}};
|
||||
use async_trait::async_trait;
|
||||
use inquire::Text;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Connect {
|
||||
@@ -50,37 +47,37 @@ impl Connect {
|
||||
|
||||
}
|
||||
|
||||
pub async fn try_refresh_token_if_exists(&self, instance: &mut Instance, api_configuration: &mut Configuration, config: &mut Config, instance_name: &String) -> Result<bool, FlowError> {
|
||||
pub async fn try_refresh_token_if_exists<'a>(&self, instance: &mut Instance, state: &'a mut GamenightState, instance_name: &String) -> Result<(bool, &'a mut GamenightState), FlowError> {
|
||||
if let Some(token) = &instance.token {
|
||||
api_configuration.bearer_access_token = Some(token.clone());
|
||||
let result = gamenight_api_client_rs::apis::default_api::post_token(api_configuration).await;
|
||||
let state = state.set_bearer_access_token(Some(token.clone()));
|
||||
let result = state.api.post_token().await;
|
||||
if let Ok(token) = result {
|
||||
let instance = config.instances.iter_mut().find(|x| x.name == *instance_name).unwrap();
|
||||
let instance = state.gamenight_configuration.instances.iter_mut().find(|x| x.name == *instance_name).unwrap();
|
||||
instance.token = token.jwt_token.clone();
|
||||
api_configuration.bearer_access_token = token.jwt_token.clone();
|
||||
Config::save(config)?;
|
||||
Ok(true)
|
||||
let state = state.set_bearer_access_token(token.jwt_token.clone());
|
||||
Config::save(&state.gamenight_configuration)?;
|
||||
Ok((true, state))
|
||||
}
|
||||
else {
|
||||
Ok(false)
|
||||
Ok((false, state))
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
Ok((false, state))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_state_on_logon(&self, instance: &mut Instance, api_configuration: &mut Configuration, config: &mut Config, instance_name: &String) -> Result<(), FlowError> {
|
||||
pub fn update_state_on_logon(&self, instance: &mut Instance, state: &mut GamenightState, instance_name: &String) -> Result<(), FlowError> {
|
||||
if self.instance.is_none() {
|
||||
instance.token = Some(api_configuration.bearer_access_token.clone().unwrap());
|
||||
config.instances.push(instance.clone());
|
||||
instance.token = Some(state.api_configuration.bearer_access_token.clone().unwrap());
|
||||
state.gamenight_configuration.instances.push(instance.clone());
|
||||
}
|
||||
else {
|
||||
let instance = config.instances.iter_mut().find(|x| x.name == *instance_name).unwrap();
|
||||
instance.token = Some(api_configuration.bearer_access_token.clone().unwrap());
|
||||
let instance = state.gamenight_configuration.instances.iter_mut().find(|x| x.name == *instance_name).unwrap();
|
||||
instance.token = Some(state.api_configuration.bearer_access_token.clone().unwrap());
|
||||
}
|
||||
config.last_instance = Some(instance_name.clone());
|
||||
state.gamenight_configuration.last_instance = Some(instance_name.clone());
|
||||
|
||||
Config::save(config)?;
|
||||
Config::save(&state.gamenight_configuration)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -98,9 +95,10 @@ impl<'a> Flow<'a> for Connect {
|
||||
};
|
||||
|
||||
let instance_name = instance.name.clone();
|
||||
state.api_configuration.base_path = instance.url.clone();
|
||||
let state = state.set_api_base_path(instance.url.clone());
|
||||
|
||||
if self.try_refresh_token_if_exists(&mut instance, &mut state.api_configuration, &mut state.gamenight_configuration, &instance_name).await? {
|
||||
let (token_refreshed, state) = self.try_refresh_token_if_exists(&mut instance, state, &instance_name).await?;
|
||||
if token_refreshed {
|
||||
let gamenight_menu_flow = GamenightMenu::new();
|
||||
gamenight_menu_flow.run(state).await
|
||||
}
|
||||
@@ -109,7 +107,7 @@ impl<'a> Flow<'a> for Connect {
|
||||
let (outcome, state) = login_flow.run(state).await?;
|
||||
|
||||
if outcome == FlowOutcome::Successful {
|
||||
self.update_state_on_logon(&mut instance, &mut state.api_configuration, &mut state.gamenight_configuration, &instance_name)?;
|
||||
self.update_state_on_logon(&mut instance, state, &instance_name)?;
|
||||
|
||||
let gamenight_menu_flow = GamenightMenu::new();
|
||||
gamenight_menu_flow.run(state).await
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::disown_post, models::GameId};
|
||||
use gamenight_api_client_rs::models::GameId;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
|
||||
@@ -22,7 +22,7 @@ impl Disown {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for Disown {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let _ = disown_post(&state.api_configuration, Some(GameId{game_id: self.game_id.to_string()})).await?;
|
||||
let _ = state.api.disown_post(Some(GameId{game_id: self.game_id.to_string()})).await?;
|
||||
|
||||
clear_screen::clear();
|
||||
Ok((FlowOutcome::Successful, state))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::join_post, models::GamenightId};
|
||||
use gamenight_api_client_rs::models::GamenightId;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
|
||||
@@ -22,7 +22,7 @@ impl Join {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for Join {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let _ = join_post(&state.api_configuration, Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
|
||||
let _ = state.api.join_post(Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
|
||||
|
||||
clear_screen::clear();
|
||||
Ok((FlowOutcome::Successful, state))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::leave_post, models::GamenightId};
|
||||
use gamenight_api_client_rs::models::GamenightId;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
|
||||
@@ -22,7 +22,7 @@ impl Leave {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for Leave {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let _ = leave_post(&state.api_configuration, Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
|
||||
let _ = state.api.leave_post(Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
|
||||
|
||||
clear_screen::clear();
|
||||
Ok((FlowOutcome::Successful, state))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
use chrono::DateTime;
|
||||
use gamenight_api_client_rs::apis::default_api::get_gamenights;
|
||||
use inquire::Select;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -22,7 +21,7 @@ impl ListGamenights {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for ListGamenights {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let response = get_gamenights(&state.api_configuration).await?;
|
||||
let response = state.api.get_gamenights().await?;
|
||||
|
||||
let mut view_flows: Vec<Box<dyn Flow<'_> + Send>> = vec![];
|
||||
|
||||
@@ -30,6 +29,10 @@ impl<'a> Flow<'a> for ListGamenights {
|
||||
let gamenight = GamenightSelectData {
|
||||
id: Uuid::parse_str(&response.id)?,
|
||||
name: response.name.clone(),
|
||||
location_id: match &response.location_id {
|
||||
None => None,
|
||||
Some(x) => Some(Uuid::parse_str(x)?)
|
||||
},
|
||||
start_time:DateTime::parse_from_rfc3339(&response.datetime)?.into(),
|
||||
owner_id: Uuid::parse_str(&response.owner_id)?
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::apis::default_api::games_get;
|
||||
use inquire::{ui::RenderConfig, Select};
|
||||
|
||||
use crate::flows::{view_game::ViewGame, exit::Exit};
|
||||
@@ -22,7 +21,7 @@ impl ListGames {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for ListGames {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let games = games_get(&state.api_configuration).await?;
|
||||
let games = state.api.games_get().await?;
|
||||
|
||||
let mut flows = games.into_iter().map(|game| -> Box<dyn Flow + Send> {
|
||||
Box::new(ViewGame::new(game.into()))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::apis::default_api::locations_get;
|
||||
use inquire::{ui::RenderConfig, Select};
|
||||
|
||||
use crate::flows::{exit::Exit, view_location::ViewLocation};
|
||||
@@ -22,10 +21,10 @@ impl ListLocations {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for ListLocations {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let locations = locations_get(&state.api_configuration).await?;
|
||||
let locations = state.api.locations_get().await?;
|
||||
|
||||
let mut flows = locations.into_iter().map(|location| -> Box<dyn Flow + Send> {
|
||||
Box::new(ViewLocation::new(location.into()))
|
||||
Box::new(ViewLocation::new(location.try_into().unwrap()))
|
||||
}).collect::<Vec::<Box::<dyn Flow + Send>>>();
|
||||
|
||||
flows.push(Box::new(Exit::new()));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::{self, authorized_location_user_ids_get, users_get}, models::{AuthorizeLocationRequestBody, LocationId, User}};
|
||||
use gamenight_api_client_rs::models::{AuthorizeLocationRequestBody, LocationId, User};
|
||||
use inquire::MultiSelect;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -47,11 +47,11 @@ impl<'a> TryFrom<&'a User> for AuthorizeMultiSelectStruct<'a> {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for LocationAuthorize {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let users = users_get(&state.api_configuration).await?;
|
||||
let users = state.api.users_get().await?;
|
||||
let location_id = LocationId {
|
||||
location_id: self.location_id.to_string()
|
||||
};
|
||||
let authorized_user_ids = authorized_location_user_ids_get(&state.api_configuration, Some(location_id)).await?;
|
||||
let authorized_user_ids = state.api.authorized_location_user_ids_get(Some(location_id)).await?;
|
||||
let authorized_user_ids : Vec<String> = authorized_user_ids.into_iter().map(|x| x.user_id).collect();
|
||||
|
||||
let options: Vec<AuthorizeMultiSelectStruct> = users.iter().map(|x| {x.try_into()}).collect::<Result<Vec<AuthorizeMultiSelectStruct>, FlowError>>()?;
|
||||
@@ -67,7 +67,7 @@ impl<'a> Flow<'a> for LocationAuthorize {
|
||||
if let Some(selections) = &selections {
|
||||
for selection in selections {
|
||||
if authorized_users.iter().find(|x| {x.id == selection.id.to_string()}).is_none() {
|
||||
default_api::location_authorize_post(&state.api_configuration, Some(
|
||||
state.api.location_authorize_post(Some(
|
||||
AuthorizeLocationRequestBody {
|
||||
location_id: self.location_id.to_string(),
|
||||
user_id: selection.id.to_string(),
|
||||
@@ -78,7 +78,7 @@ impl<'a> Flow<'a> for LocationAuthorize {
|
||||
}
|
||||
for authorized_user in authorized_users {
|
||||
if selections.iter().find(|x| {x.id.to_string() == authorized_user.id}).is_none() {
|
||||
default_api::location_authorize_post(&state.api_configuration, Some(
|
||||
state.api.location_authorize_post(Some(
|
||||
AuthorizeLocationRequestBody {
|
||||
location_id: self.location_id.to_string(),
|
||||
user_id: authorized_user.id.to_string(),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::{configuration::Configuration, default_api::get_token}, models};
|
||||
use gamenight_api_client_rs::models;
|
||||
use inquire::{Password, Text};
|
||||
|
||||
use super::*;
|
||||
@@ -18,7 +18,6 @@ impl Login {
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for Login {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let configuration = Configuration::new();
|
||||
|
||||
let username = Text::new("What is your login?").prompt()?;
|
||||
let password = Password::new("what is your password?")
|
||||
@@ -27,11 +26,11 @@ impl<'a> Flow<'a> for Login {
|
||||
|
||||
let login = models::Login::new(username, password);
|
||||
|
||||
let result = get_token(&configuration, Some(login)).await?;
|
||||
let result = state.api.get_token(Some(login)).await?;
|
||||
|
||||
clear_screen::clear();
|
||||
if let Some(token) = result.jwt_token {
|
||||
state.api_configuration.bearer_access_token = Some(token);
|
||||
state.set_bearer_access_token(Some(token));
|
||||
Ok((FlowOutcome::Successful, state))
|
||||
} else {
|
||||
Err(FlowError{error: "Unexpected response".to_string()})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use gamenight_api_client_rs::apis::default_api::{DefaultApi, DefaultApiClient};
|
||||
use std::{fmt::Display, num::ParseIntError};
|
||||
|
||||
use std::sync::{Arc, MutexGuard, PoisonError};
|
||||
use async_trait::async_trait;
|
||||
use chrono::ParseError;
|
||||
use gamenight_api_client_rs::apis::{configuration::Configuration, Error};
|
||||
@@ -38,10 +39,12 @@ mod location_authorize;
|
||||
mod remove_game;
|
||||
|
||||
pub struct GamenightState {
|
||||
api_configuration: Configuration,
|
||||
api_configuration: Arc<Configuration>,
|
||||
api: Box<dyn DefaultApi>,
|
||||
gamenight_configuration: Config,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Claims {
|
||||
exp: i64,
|
||||
@@ -50,8 +53,10 @@ pub struct Claims {
|
||||
|
||||
impl GamenightState {
|
||||
pub fn new() -> Self{
|
||||
let config = Arc::new(Configuration::new());
|
||||
Self {
|
||||
api_configuration: Configuration::new(),
|
||||
api_configuration: config.clone(),
|
||||
api: Box::new(DefaultApiClient::new(config.clone())),
|
||||
gamenight_configuration: Config::new()
|
||||
}
|
||||
}
|
||||
@@ -67,6 +72,22 @@ impl GamenightState {
|
||||
|
||||
Ok(claims.uid)
|
||||
}
|
||||
|
||||
pub fn set_bearer_access_token(&mut self, token: Option<String>) -> &mut Self {
|
||||
let mut config : Configuration = Arc::<Configuration>::into_inner(self.api_configuration.clone()).unwrap_or(Configuration::new());
|
||||
config.bearer_access_token = token;
|
||||
self.api_configuration = Arc::from(config);
|
||||
self.api = Box::new(DefaultApiClient::new(self.api_configuration.clone()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_api_base_path(&mut self, base_path: String) -> &mut Self {
|
||||
let mut config : Configuration = Arc::<Configuration>::into_inner(self.api_configuration.clone()).unwrap_or(Configuration::new());
|
||||
config.base_path = base_path;
|
||||
self.api_configuration = Arc::from(config);
|
||||
self.api = Box::new(DefaultApiClient::new(self.api_configuration.clone()));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GamenightState {
|
||||
@@ -136,6 +157,30 @@ impl From<jsonwebtoken::errors::Error> for FlowError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PoisonError<&mut Configuration>> for FlowError {
|
||||
fn from(value: PoisonError<&mut Configuration>) -> Self {
|
||||
Self {
|
||||
error: value.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PoisonError<Configuration>> for FlowError {
|
||||
fn from(value: PoisonError<Configuration>) -> Self {
|
||||
Self {
|
||||
error: value.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PoisonError<std::sync::MutexGuard<'_, Configuration>>> for FlowError {
|
||||
fn from(value: PoisonError<MutexGuard<'_, Configuration>>) -> Self {
|
||||
Self {
|
||||
error: value.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum FlowOutcome {
|
||||
Successful,
|
||||
|
||||
@@ -3,9 +3,7 @@ use std::fmt::Display;
|
||||
use super::{Flow, FlowError, FlowOutcome, FlowResult, GamenightState};
|
||||
use crate::domain::location_select_data::LocationSelectData;
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::apis::default_api::locations_get;
|
||||
use gamenight_api_client_rs::models::OwnGameRequestBody;
|
||||
use gamenight_api_client_rs::apis::default_api::own_post;
|
||||
use inquire::{Confirm, Select};
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -35,13 +33,13 @@ impl<'a> Flow<'a> for Own {
|
||||
if owned {
|
||||
if let Some(willing_to_travel) = Confirm::new("Are you willing to travel with this game?").prompt_skippable()? {
|
||||
if !willing_to_travel {
|
||||
let locations = locations_get(&state.api_configuration).await?.iter().map(|x| { x.try_into() }).collect::<Result<Vec<LocationSelectData>, FlowError>>()?;
|
||||
let locations = state.api.locations_get().await?.iter().map(|x| { x.try_into() }).collect::<Result<Vec<LocationSelectData>, FlowError>>()?;
|
||||
if let Some(location) = Select::new("What location can this game be played?", locations).prompt_skippable()? {
|
||||
own_game_request.location_id = Some(location.id.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = own_post(&state.api_configuration, Some(own_game_request)).await?;
|
||||
let _ = state.api.own_post(Some(own_game_request)).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ impl<'a> Flow<'a> for RemoveGame {
|
||||
let req = GameId {
|
||||
game_id: self.game.id.to_string()
|
||||
};
|
||||
gamenight_api_client_rs::apis::default_api::game_delete(&state.api_configuration, Some(req)).await?;
|
||||
state.api.game_delete(Some(req)).await?;
|
||||
//Hack to return to right stack item, skipping detail view that doesn't exist.
|
||||
Ok((FlowOutcome::Abort, state))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::rename_game_post, models::RenameGameRequestBody};
|
||||
use gamenight_api_client_rs::models::RenameGameRequestBody;
|
||||
use inquire::Text;
|
||||
|
||||
use crate::domain::game::Game;
|
||||
@@ -32,7 +32,7 @@ impl<'a> Flow<'a> for RenameGame {
|
||||
id: self.game.id.to_string(),
|
||||
name
|
||||
};
|
||||
rename_game_post(&state.api_configuration, Some(req)).await?;
|
||||
state.api.rename_game_post(Some(req)).await?;
|
||||
|
||||
return Ok((FlowOutcome::Successful, state))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
use gamenight_api_client_rs::{apis::default_api::{game_get, owned_games_get}, models::{GameId, UserId}};
|
||||
use gamenight_api_client_rs::models::{GameId, UserId};
|
||||
use inquire::Select;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -24,15 +24,15 @@ impl ViewGame {
|
||||
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();
|
||||
let game: Game = state.api.game_get(Some(game_id)).await?.into();
|
||||
|
||||
println!("{}", game);
|
||||
|
||||
let my_uid = state.get_user_id()?;
|
||||
let request = UserId{ user_id: my_uid.to_string() };
|
||||
let owned_games: Vec<Uuid> = owned_games_get(&state.api_configuration, Some(request)).await?
|
||||
let owned_games: Vec<Uuid> = state.api.owned_games_get(Some(request)).await?
|
||||
.iter().map(|x| -> Result<Uuid, FlowError> {
|
||||
Ok(Uuid::parse_str(x)?)
|
||||
Ok(Uuid::parse_str(&x.game_id)?)
|
||||
}).collect::<Result<Vec<Uuid>, FlowError>>()?;
|
||||
|
||||
let own_or_disown: Box<dyn Flow<'a> + Send> =
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use crate::domain::gamenight::Gamenight;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use futures::future::join_all;
|
||||
use gamenight_api_client_rs::{apis::default_api::{game_get, owned_games_get, participants_get, user_get, GameGetError}, models::{self, GameId, GamenightId, UserId}};
|
||||
use gamenight_api_client_rs::models::{GameId, GamenightId, LocationId, OwnedGame, UserId};
|
||||
use inquire::Select;
|
||||
|
||||
use crate::{domain::{game::Game, gamenight_select_data::GamenightSelectData, owned_games::OwnedGames, participants::Participants}, flows::{exit::Exit, join::Join, leave::Leave}};
|
||||
|
||||
use super::*;
|
||||
use crate::{domain::{gamenight_select_data::GamenightSelectData, owned_games::OwnedGames, participants::Participants}, flows::{exit::Exit, join::Join, leave::Leave}};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ViewGamenight {
|
||||
@@ -30,25 +28,35 @@ impl<'a> Flow<'a> for ViewGamenight {
|
||||
id: self.gamenight_select_data.id,
|
||||
start_time: self.gamenight_select_data.start_time,
|
||||
name: self.gamenight_select_data.name.clone(),
|
||||
organizer: user_get(&state.api_configuration, Some(UserId{user_id: self.gamenight_select_data.owner_id.to_string()})).await?.try_into()?,
|
||||
location: None,
|
||||
organizer: state.api.user_get(Some(UserId{user_id: self.gamenight_select_data.owner_id.to_string()})).await?.try_into()?,
|
||||
participants: Participants(vec![]),
|
||||
owned_games: OwnedGames(HashMap::new())
|
||||
};
|
||||
|
||||
let participants = participants_get(&state.api_configuration, Some(GamenightId{gamenight_id: gamenight.id.to_string()})).await?;
|
||||
gamenight.location = match self.gamenight_select_data.location_id {
|
||||
None => None,
|
||||
Some(l) => Some(state.api.location_get(Some(LocationId{location_id: l.to_string()})).await?.try_into()?)
|
||||
};
|
||||
let participants = state.api.participants_get(Some(GamenightId{gamenight_id: gamenight.id.to_string()})).await?;
|
||||
|
||||
for participant in participants.participants.iter() {
|
||||
gamenight.participants.0.push(user_get(&state.api_configuration, Some(UserId{user_id: participant.clone()})).await?.try_into()?);
|
||||
gamenight.participants.0.push(state.api.user_get(Some(UserId{user_id: participant.clone()})).await?.try_into()?);
|
||||
}
|
||||
|
||||
for user in &gamenight.participants.0 {
|
||||
let request = UserId{ user_id: user.id.to_string() };
|
||||
let games: Vec<Game> = join_all(owned_games_get(&state.api_configuration, Some(request)).await?
|
||||
.iter().map(async |game_id| -> Result<models::Game, Error<GameGetError>> {
|
||||
let request = GameId{ game_id: game_id.clone() };
|
||||
game_get(&state.api_configuration, Some(request)).await
|
||||
})).await.into_iter().collect::<Result<Vec<models::Game>, Error<GameGetError>>>()?.into_iter().map(Into::into).collect();
|
||||
gamenight.owned_games.0.insert(user.username.clone(), games);
|
||||
let owned_games_refs: Vec<OwnedGame> = state.api.owned_games_get(Some(request)).await?;
|
||||
let mut owned_games = vec![];
|
||||
for owned_games_ref in owned_games_refs {
|
||||
let game = state.api.game_get(Some(GameId{ game_id: owned_games_ref.game_id.clone()})).await?.into();
|
||||
let location = match owned_games_ref.location_id {
|
||||
None => None,
|
||||
Some(x) => Some(state.api.location_get(Some(LocationId{location_id: x})).await?.try_into()?)
|
||||
};
|
||||
owned_games.push((game, location));
|
||||
}
|
||||
gamenight.owned_games.0.insert(user.username.clone(), owned_games);
|
||||
}
|
||||
|
||||
println!("{}", gamenight);
|
||||
|
||||
@@ -6,9 +6,9 @@ use flows::{main::Main, Flow, GamenightState};
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut state = GamenightState::new();
|
||||
let mainflow = Main::new();
|
||||
let main_flow = Main::new();
|
||||
clear_screen::clear();
|
||||
if let Err(x) = mainflow.run(&mut state).await {
|
||||
if let Err(x) = main_flow.run(&mut state).await {
|
||||
println!("{}", x.error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ pub fn disown_game(conn: &mut PgConnection, owned_game: OwnedGame) -> Result<usi
|
||||
.execute(conn)?)
|
||||
}
|
||||
|
||||
pub fn owned_games(conn: &mut PgConnection, uuid: Uuid) -> Result<Vec<Uuid>, DatabaseError> {
|
||||
pub fn owned_games(conn: &mut PgConnection, uuid: Uuid) -> Result<Vec<(Uuid, Option<Uuid>)>, DatabaseError> {
|
||||
Ok(owned_game::table
|
||||
.select(owned_game::game_id)
|
||||
.select((owned_game::game_id, owned_game::location_id))
|
||||
.filter(owned_game::user_id.eq(uuid))
|
||||
.get_results(conn)?)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user