Implements leaving on the client side

This commit is contained in:
Dennis Brentjes 2025-06-24 16:49:21 +02:00
parent d11e31149b
commit fbe456a0f5
43 changed files with 1730 additions and 10 deletions

View File

@ -1,8 +1,3 @@
/target/ /target/
**/*.rs.bk **/*.rs.bk
Cargo.lock Cargo.lock
.openapi-generator-ignore
.openapi-generator/
.travis.yml
docs/
src/

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1,33 @@
.gitignore
.travis.yml
Cargo.toml
README.md
docs/AddGamenightRequestBody.md
docs/DefaultApi.md
docs/Failure.md
docs/Gamenight.md
docs/GamenightId.md
docs/GetGamenightRequestBody.md
docs/Login.md
docs/Participants.md
docs/Registration.md
docs/Token.md
docs/User.md
docs/UserId.md
git_push.sh
src/apis/configuration.rs
src/apis/default_api.rs
src/apis/mod.rs
src/lib.rs
src/models/add_gamenight_request_body.rs
src/models/failure.rs
src/models/gamenight.rs
src/models/gamenight_id.rs
src/models/get_gamenight_request_body.rs
src/models/login.rs
src/models/mod.rs
src/models/participants.rs
src/models/registration.rs
src/models/token.rs
src/models/user.rs
src/models/user_id.rs

View File

@ -0,0 +1 @@
7.13.0

View File

@ -0,0 +1 @@
language: rust

View File

@ -31,6 +31,7 @@ Class | Method | HTTP request | Description
*DefaultApi* | [**get_gamenights**](docs/DefaultApi.md#get_gamenights) | **GET** /gamenights | Get a all gamenights *DefaultApi* | [**get_gamenights**](docs/DefaultApi.md#get_gamenights) | **GET** /gamenights | Get a all gamenights
*DefaultApi* | [**get_token**](docs/DefaultApi.md#get_token) | **GET** /token | *DefaultApi* | [**get_token**](docs/DefaultApi.md#get_token) | **GET** /token |
*DefaultApi* | [**join_post**](docs/DefaultApi.md#join_post) | **POST** /join | *DefaultApi* | [**join_post**](docs/DefaultApi.md#join_post) | **POST** /join |
*DefaultApi* | [**leave_post**](docs/DefaultApi.md#leave_post) | **POST** /leave |
*DefaultApi* | [**participants_get**](docs/DefaultApi.md#participants_get) | **GET** /participants | Get all participants for a gamenight *DefaultApi* | [**participants_get**](docs/DefaultApi.md#participants_get) | **GET** /participants | Get all participants for a gamenight
*DefaultApi* | [**post_gamenight**](docs/DefaultApi.md#post_gamenight) | **POST** /gamenight | *DefaultApi* | [**post_gamenight**](docs/DefaultApi.md#post_gamenight) | **POST** /gamenight |
*DefaultApi* | [**post_register**](docs/DefaultApi.md#post_register) | **POST** /user | *DefaultApi* | [**post_register**](docs/DefaultApi.md#post_register) | **POST** /user |

View File

@ -0,0 +1,12 @@
# AddGamenightRequestBody
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**name** | Option<**String**> | | [optional]
**datetime** | 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)

View File

@ -0,0 +1,278 @@
# \DefaultApi
All URIs are relative to *http://localhost:8080*
Method | HTTP request | Description
------------- | ------------- | -------------
[**get_gamenight**](DefaultApi.md#get_gamenight) | **GET** /gamenight |
[**get_gamenights**](DefaultApi.md#get_gamenights) | **GET** /gamenights | Get a all gamenights
[**get_token**](DefaultApi.md#get_token) | **GET** /token |
[**join_post**](DefaultApi.md#join_post) | **POST** /join |
[**leave_post**](DefaultApi.md#leave_post) | **POST** /leave |
[**participants_get**](DefaultApi.md#participants_get) | **GET** /participants | Get all participants for a gamenight
[**post_gamenight**](DefaultApi.md#post_gamenight) | **POST** /gamenight |
[**post_register**](DefaultApi.md#post_register) | **POST** /user |
[**user_get**](DefaultApi.md#user_get) | **GET** /user |
## get_gamenight
> models::Gamenight get_gamenight(get_gamenight_request_body)
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**get_gamenight_request_body** | Option<[**GetGamenightRequestBody**](GetGamenightRequestBody.md)> | | |
### Return type
[**models::Gamenight**](Gamenight.md)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## get_gamenights
> Vec<models::Gamenight> get_gamenights()
Get a all gamenights
Retrieve the list of gamenights on this gamenight server. Requires authorization.
### Parameters
This endpoint does not need any parameter.
### Return type
[**Vec<models::Gamenight>**](Gamenight.md)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## get_token
> models::Token get_token(login)
Submit your credentials to get a JWT-token to use with the rest of the api.
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**login** | Option<[**Login**](Login.md)> | | |
### Return type
[**models::Token**](Token.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## join_post
> join_post(gamenight_id)
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**gamenight_id** | Option<[**GamenightId**](GamenightId.md)> | | |
### Return type
(empty response body)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## leave_post
> leave_post(gamenight_id)
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**gamenight_id** | Option<[**GamenightId**](GamenightId.md)> | | |
### Return type
(empty response body)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## participants_get
> models::Participants participants_get(gamenight_id)
Get all participants for a gamenight
Retrieve the participants of a single gamenight by id.
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**gamenight_id** | Option<[**GamenightId**](GamenightId.md)> | | |
### Return type
[**models::Participants**](Participants.md)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## post_gamenight
> post_gamenight(add_gamenight_request_body)
Add a gamenight by providing a name and a date, only available when providing an JWT token.
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**add_gamenight_request_body** | Option<[**AddGamenightRequestBody**](AddGamenightRequestBody.md)> | | |
### Return type
(empty response body)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## post_register
> post_register(registration)
Create a new user given a registration token and user information, username and email must be unique, and password and password_repeat must match.
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**registration** | Option<[**Registration**](Registration.md)> | | |
### Return type
(empty response body)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
## user_get
> models::User user_get(user_id)
Get a user from primary id
### Parameters
Name | Type | Description | Required | Notes
------------- | ------------- | ------------- | ------------- | -------------
**user_id** | Option<[**UserId**](UserId.md)> | | |
### Return type
[**models::User**](User.md)
### Authorization
[JWT-Auth](../README.md#JWT-Auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

View File

@ -0,0 +1,11 @@
# Failure
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**message** | 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)

View File

@ -0,0 +1,14 @@
# Gamenight
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **String** | |
**name** | **String** | |
**datetime** | **String** | |
**owner_id** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,11 @@
# GamenightId
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**gamenight_id** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,11 @@
# GetGamenightRequest
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**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)

View File

@ -0,0 +1,11 @@
# GetGamenightRequestBody
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**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)

View File

@ -0,0 +1,11 @@
# GetToken401Response
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**message** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,12 @@
# Login
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**username** | **String** | |
**password** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,11 @@
# Participants
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**participants** | **Vec<String>** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,15 @@
# Registration
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**username** | **String** | |
**email** | **String** | |
**password** | **String** | |
**password_repeat** | **String** | |
**registration_token** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,11 @@
# Token
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**jwt_token** | 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)

View File

@ -0,0 +1,13 @@
# User
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **String** | |
**username** | **String** | |
**email** | 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)

View File

@ -0,0 +1,11 @@
# UserId
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**user_id** | **String** | |
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,51 @@
/*
* Gamenight
*
* Api specifaction for a Gamenight server
*
* The version of the OpenAPI document: 1.0
* Contact: dennis@brentj.es
* Generated by: https://openapi-generator.tech
*/
#[derive(Debug, Clone)]
pub struct Configuration {
pub base_path: String,
pub user_agent: Option<String>,
pub client: reqwest::Client,
pub basic_auth: Option<BasicAuth>,
pub oauth_access_token: Option<String>,
pub bearer_access_token: Option<String>,
pub api_key: Option<ApiKey>,
}
pub type BasicAuth = (String, Option<String>);
#[derive(Debug, Clone)]
pub struct ApiKey {
pub prefix: Option<String>,
pub key: String,
}
impl Configuration {
pub fn new() -> Configuration {
Configuration::default()
}
}
impl Default for Configuration {
fn default() -> Self {
Configuration {
base_path: "http://localhost:8080".to_owned(),
user_agent: Some("OpenAPI-Generator/1.0/rust".to_owned()),
client: reqwest::Client::new(),
basic_auth: None,
oauth_access_token: None,
bearer_access_token: None,
api_key: None,
}
}
}

View File

@ -0,0 +1,414 @@
/*
* Gamenight
*
* Api specifaction for a Gamenight server
*
* The version of the OpenAPI document: 1.0
* Contact: dennis@brentj.es
* Generated by: https://openapi-generator.tech
*/
use reqwest;
use serde::{Deserialize, Serialize, de::Error as _};
use crate::{apis::ResponseContent, models};
use super::{Error, configuration, ContentType};
/// struct for typed errors of method [`get_gamenight`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetGamenightError {
Status401(models::Failure),
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_gamenights`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetGamenightsError {
Status400(models::Failure),
Status401(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_token`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetTokenError {
Status401(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`join_post`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum JoinPostError {
Status401(models::Failure),
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`leave_post`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum LeavePostError {
Status401(models::Failure),
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`participants_get`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ParticipantsGetError {
Status400(models::Failure),
Status401(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`post_gamenight`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PostGamenightError {
Status401(models::Failure),
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`post_register`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PostRegisterError {
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`user_get`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UserGetError {
Status401(models::Failure),
Status404(models::Failure),
Status422(models::Failure),
UnknownValue(serde_json::Value),
}
pub async fn get_gamenight(configuration: &configuration::Configuration, get_gamenight_request_body: Option<models::GetGamenightRequestBody>) -> Result<models::Gamenight, Error<GetGamenightError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_get_gamenight_request_body = get_gamenight_request_body;
let uri_str = format!("{}/gamenight", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_get_gamenight_request_body);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Gamenight`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Gamenight`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetGamenightError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Retrieve the list of gamenights on this gamenight server. Requires authorization.
pub async fn get_gamenights(configuration: &configuration::Configuration, ) -> Result<Vec<models::Gamenight>, Error<GetGamenightsError>> {
let uri_str = format!("{}/gamenights", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Gamenight&gt;`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Gamenight&gt;`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetGamenightsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Submit your credentials to get a JWT-token to use with the rest of the api.
pub async fn get_token(configuration: &configuration::Configuration, login: Option<models::Login>) -> Result<models::Token, Error<GetTokenError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_login = login;
let uri_str = format!("{}/token", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
req_builder = req_builder.json(&p_login);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Token`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Token`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetTokenError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
pub async fn join_post(configuration: &configuration::Configuration, gamenight_id: Option<models::GamenightId>) -> Result<(), Error<JoinPostError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_gamenight_id = gamenight_id;
let uri_str = format!("{}/join", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_gamenight_id);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<JoinPostError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
pub async fn leave_post(configuration: &configuration::Configuration, gamenight_id: Option<models::GamenightId>) -> Result<(), Error<LeavePostError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_gamenight_id = gamenight_id;
let uri_str = format!("{}/leave", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_gamenight_id);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<LeavePostError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Retrieve the participants of a single gamenight by id.
pub async fn participants_get(configuration: &configuration::Configuration, gamenight_id: Option<models::GamenightId>) -> Result<models::Participants, Error<ParticipantsGetError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_gamenight_id = gamenight_id;
let uri_str = format!("{}/participants", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_gamenight_id);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Participants`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Participants`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ParticipantsGetError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Add a gamenight by providing a name and a date, only available when providing an JWT token.
pub async fn post_gamenight(configuration: &configuration::Configuration, add_gamenight_request_body: Option<models::AddGamenightRequestBody>) -> Result<(), Error<PostGamenightError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_add_gamenight_request_body = add_gamenight_request_body;
let uri_str = format!("{}/gamenight", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_add_gamenight_request_body);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<PostGamenightError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Create a new user given a registration token and user information, username and email must be unique, and password and password_repeat must match.
pub async fn post_register(configuration: &configuration::Configuration, registration: Option<models::Registration>) -> Result<(), Error<PostRegisterError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_registration = registration;
let uri_str = format!("{}/user", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_registration);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<PostRegisterError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Get a user from primary id
pub async fn user_get(configuration: &configuration::Configuration, user_id: Option<models::UserId>) -> Result<models::User, Error<UserGetError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_user_id = user_id;
let uri_str = format!("{}/user", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_user_id);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::User`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::User`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UserGetError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}

View File

@ -0,0 +1,116 @@
use std::error;
use std::fmt;
#[derive(Debug, Clone)]
pub struct ResponseContent<T> {
pub status: reqwest::StatusCode,
pub content: String,
pub entity: Option<T>,
}
#[derive(Debug)]
pub enum Error<T> {
Reqwest(reqwest::Error),
Serde(serde_json::Error),
Io(std::io::Error),
ResponseError(ResponseContent<T>),
}
impl <T> fmt::Display for Error<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (module, e) = match self {
Error::Reqwest(e) => ("reqwest", e.to_string()),
Error::Serde(e) => ("serde", e.to_string()),
Error::Io(e) => ("IO", e.to_string()),
Error::ResponseError(e) => ("response", format!("status code {}", e.status)),
};
write!(f, "error in {}: {}", module, e)
}
}
impl <T: fmt::Debug> error::Error for Error<T> {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match self {
Error::Reqwest(e) => e,
Error::Serde(e) => e,
Error::Io(e) => e,
Error::ResponseError(_) => return None,
})
}
}
impl <T> From<reqwest::Error> for Error<T> {
fn from(e: reqwest::Error) -> Self {
Error::Reqwest(e)
}
}
impl <T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
Error::Serde(e)
}
}
impl <T> From<std::io::Error> for Error<T> {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}
pub fn urlencode<T: AsRef<str>>(s: T) -> String {
::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
}
pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> {
if let serde_json::Value::Object(object) = value {
let mut params = vec![];
for (key, value) in object {
match value {
serde_json::Value::Object(_) => params.append(&mut parse_deep_object(
&format!("{}[{}]", prefix, key),
value,
)),
serde_json::Value::Array(array) => {
for (i, value) in array.iter().enumerate() {
params.append(&mut parse_deep_object(
&format!("{}[{}][{}]", prefix, key, i),
value,
));
}
},
serde_json::Value::String(s) => params.push((format!("{}[{}]", prefix, key), s.clone())),
_ => params.push((format!("{}[{}]", prefix, key), value.to_string())),
}
}
return params;
}
unimplemented!("Only objects are supported with style=deepObject")
}
/// Internal use only
/// A content type supported by this client.
#[allow(dead_code)]
enum ContentType {
Json,
Text,
Unsupported(String)
}
impl From<&str> for ContentType {
fn from(content_type: &str) -> Self {
if content_type.starts_with("application") && content_type.contains("json") {
return Self::Json;
} else if content_type.starts_with("text/plain") {
return Self::Text;
} else {
return Self::Unsupported(content_type.to_string());
}
}
}
pub mod default_api;
pub mod configuration;

View File

@ -0,0 +1,11 @@
#![allow(unused_imports)]
#![allow(clippy::too_many_arguments)]
extern crate serde_repr;
extern crate serde;
extern crate serde_json;
extern crate url;
extern crate reqwest;
pub mod apis;
pub mod models;

View File

@ -0,0 +1,30 @@
/*
* Gamenight
*
* Api specifaction 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 AddGamenightRequestBody {
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(rename = "datetime", skip_serializing_if = "Option::is_none")]
pub datetime: Option<String>,
}
impl AddGamenightRequestBody {
pub fn new() -> AddGamenightRequestBody {
AddGamenightRequestBody {
name: None,
datetime: None,
}
}
}

View File

@ -0,0 +1,29 @@
/*
* Gamenight
*
* Api specifaction 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};
/// Failure : Failure Reason
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Failure {
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
impl Failure {
/// Failure Reason
pub fn new() -> Failure {
Failure {
message: None,
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Gamenight
*
* Api specifaction 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 Gamenight {
#[serde(rename = "id")]
pub id: String,
#[serde(rename = "name")]
pub name: String,
#[serde(rename = "datetime")]
pub datetime: String,
#[serde(rename = "owner_id")]
pub owner_id: String,
}
impl Gamenight {
pub fn new(id: String, name: String, datetime: String, owner_id: String) -> Gamenight {
Gamenight {
id,
name,
datetime,
owner_id,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 GamenightId {
#[serde(rename = "gamenight_id")]
pub gamenight_id: String,
}
impl GamenightId {
pub fn new(gamenight_id: String) -> GamenightId {
GamenightId {
gamenight_id,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 GetGamenightRequest {
#[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
}
impl GetGamenightRequest {
pub fn new() -> GetGamenightRequest {
GetGamenightRequest {
id: None,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 GetGamenightRequestBody {
#[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
}
impl GetGamenightRequestBody {
pub fn new() -> GetGamenightRequestBody {
GetGamenightRequestBody {
id: None,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 GetToken401Response {
#[serde(rename = "message")]
pub message: String,
}
impl GetToken401Response {
pub fn new(message: String) -> GetToken401Response {
GetToken401Response {
message,
}
}
}

View File

@ -0,0 +1,30 @@
/*
* Gamenight
*
* Api specifaction 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 Login {
#[serde(rename = "username")]
pub username: String,
#[serde(rename = "password")]
pub password: String,
}
impl Login {
pub fn new(username: String, password: String) -> Login {
Login {
username,
password,
}
}
}

View File

@ -0,0 +1,22 @@
pub mod add_gamenight_request_body;
pub use self::add_gamenight_request_body::AddGamenightRequestBody;
pub mod failure;
pub use self::failure::Failure;
pub mod gamenight;
pub use self::gamenight::Gamenight;
pub mod gamenight_id;
pub use self::gamenight_id::GamenightId;
pub mod get_gamenight_request_body;
pub use self::get_gamenight_request_body::GetGamenightRequestBody;
pub mod login;
pub use self::login::Login;
pub mod participants;
pub use self::participants::Participants;
pub mod registration;
pub use self::registration::Registration;
pub mod token;
pub use self::token::Token;
pub mod user;
pub use self::user::User;
pub mod user_id;
pub use self::user_id::UserId;

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 Participants {
#[serde(rename = "participants")]
pub participants: Vec<String>,
}
impl Participants {
pub fn new(participants: Vec<String>) -> Participants {
Participants {
participants,
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Gamenight
*
* Api specifaction 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 Registration {
#[serde(rename = "username")]
pub username: String,
#[serde(rename = "email")]
pub email: String,
#[serde(rename = "password")]
pub password: String,
#[serde(rename = "password_repeat")]
pub password_repeat: String,
#[serde(rename = "registration_token")]
pub registration_token: String,
}
impl Registration {
pub fn new(username: String, email: String, password: String, password_repeat: String, registration_token: String) -> Registration {
Registration {
username,
email,
password,
password_repeat,
registration_token,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 Token {
#[serde(rename = "jwt_token", skip_serializing_if = "Option::is_none")]
pub jwt_token: Option<String>,
}
impl Token {
pub fn new() -> Token {
Token {
jwt_token: None,
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Gamenight
*
* Api specifaction 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 User {
#[serde(rename = "id")]
pub id: String,
#[serde(rename = "username")]
pub username: String,
#[serde(rename = "email", skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
}
impl User {
pub fn new(id: String, username: String) -> User {
User {
id,
username,
email: None,
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Gamenight
*
* Api specifaction 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 UserId {
#[serde(rename = "user_id")]
pub user_id: String,
}
impl UserId {
pub fn new(user_id: String) -> UserId {
UserId {
user_id,
}
}
}

166
gamenight-cli/Cargo.lock generated
View File

@ -160,6 +160,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "deranged"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
"powerfmt",
]
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.5" version = "0.2.5"
@ -263,10 +272,26 @@ dependencies = [
"dyn-clone", "dyn-clone",
"gamenight-api-client-rs", "gamenight-api-client-rs",
"inquire", "inquire",
"jsonwebtoken",
"serde",
"serde_json",
"tokio", "tokio",
"uuid", "uuid",
] ]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.3.3" version = "0.3.3"
@ -549,6 +574,21 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "jsonwebtoken"
version = "9.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
dependencies = [
"base64",
"js-sys",
"pem",
"ring",
"serde",
"serde_json",
"simple_asn1",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.172" version = "0.2.172"
@ -640,6 +680,31 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@ -687,6 +752,16 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "pem"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
dependencies = [
"base64",
"serde",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.1" version = "2.3.1"
@ -714,6 +789,12 @@ dependencies = [
"zerovec", "zerovec",
] ]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.95" version = "1.0.95"
@ -781,6 +862,20 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.16",
"libc",
"untrusted",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.25" version = "0.1.25"
@ -896,6 +991,18 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "simple_asn1"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
dependencies = [
"num-bigint",
"num-traits",
"thiserror",
"time",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.1" version = "1.15.1"
@ -949,6 +1056,26 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "1.1.8" version = "1.1.8"
@ -959,6 +1086,37 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "time"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "time-macros"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
"num-conv",
"time-core",
]
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.8.1" version = "0.8.1"
@ -1092,6 +1250,12 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.4" version = "2.5.4"
@ -1115,7 +1279,7 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.3.3",
"js-sys", "js-sys",
"serde", "serde",
"wasm-bindgen", "wasm-bindgen",

View File

@ -11,3 +11,6 @@ async-trait = "0.1"
dyn-clone = "1.0" dyn-clone = "1.0"
chrono = "0.4" chrono = "0.4"
uuid = { version = "1.3.0", features = ["serde", "v4"] } uuid = { version = "1.3.0", features = ["serde", "v4"] }
jsonwebtoken = "9.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View File

@ -0,0 +1,34 @@
use std::fmt::Display;
use async_trait::async_trait;
use gamenight_api_client_rs::{apis::default_api::leave_post, models::GamenightId};
use uuid::Uuid;
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
#[derive(Clone)]
pub struct Leave {
gamenight_id: Uuid
}
impl Leave {
pub fn new(gamenight_id: Uuid) -> Self {
Self {
gamenight_id
}
}
}
#[async_trait]
impl<'a> Flow<'a> for Leave {
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
let _ = leave_post(&state.configuration, Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
Ok((FlowOutcome::Successful, state))
}
}
impl Display for Leave {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Leave")
}
}

View File

@ -14,6 +14,7 @@ mod list_gamenights;
mod add_gamenight; mod add_gamenight;
mod view_gamenight; mod view_gamenight;
mod join; mod join;
mod leave;
pub struct GamenightState { pub struct GamenightState {
configuration: Configuration, configuration: Configuration,

View File

@ -1,9 +1,11 @@
use gamenight_api_client_rs::{apis::default_api::{participants_get, user_get}, models::{GamenightId, UserId}}; use gamenight_api_client_rs::{apis::default_api::{participants_get, user_get}, models::{GamenightId, UserId}};
use inquire::Select; use inquire::Select;
use jsonwebtoken::{decode, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use crate::{domain::{gamenight::Gamenight, user::User}, flows::{exit::Exit, join::Join}}; use crate::{domain::{gamenight::Gamenight, user::User}, flows::{exit::Exit, join::Join, leave::Leave}};
use super::*; use super::*;
@ -21,12 +23,26 @@ impl ViewGamenight {
} }
fn vec_user_to_usernames_string(users: Vec<User>) -> String { fn vec_user_to_usernames_string(users: &Vec<User>) -> String {
let string_list: Vec<String> = users.iter().map(|x| {format!("{}", x)}).collect(); let string_list: Vec<String> = users.iter().map(|x| {format!("{}", x)}).collect();
string_list.join(", ") string_list.join(", ")
} }
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
exp: i64,
uid: Uuid
}
impl From<jsonwebtoken::errors::Error> for FlowError {
fn from(value: jsonwebtoken::errors::Error) -> Self {
Self {
error: value.to_string()
}
}
}
#[async_trait] #[async_trait]
impl<'a> Flow<'a> for ViewGamenight { impl<'a> Flow<'a> for ViewGamenight {
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> { async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
@ -41,9 +57,25 @@ impl<'a> Flow<'a> for ViewGamenight {
}); });
} }
println!("{}\nwho: {}", self.gamenight, vec_user_to_usernames_string(users)); println!("{}\nwho: {}", self.gamenight, vec_user_to_usernames_string(&users));
let decoding_key = DecodingKey::from_secret(b"");
let mut validation = Validation::default();
validation.insecure_disable_signature_validation();
let claims = decode::<Claims>(
&state.configuration.bearer_access_token.as_ref().unwrap(),
&decoding_key,
&validation)?.claims;
let join_or_leave: Box<dyn Flow<'a> + Send> =
if users.iter().map(|x| {x.id}).find(|x| *x == claims.uid) != None {
Box::new(Leave::new(claims.uid))
}
else {
Box::new(Join::new(claims.uid))
};
let options: Vec<Box<dyn Flow<'a> + Send>> = vec![ let options: Vec<Box<dyn Flow<'a> + Send>> = vec![
Box::new(Join::new(self.gamenight.id)), join_or_leave,
Box::new(Exit::new()) Box::new(Exit::new())
]; ];
let choice = Select::new("What do you want to do:", options) let choice = Select::new("What do you want to do:", options)