mirror of
https://github.com/pcvolkmer/arsnova-client.git
synced 2025-04-19 19:16:51 +00:00
feat: apply typestate pattern to client
This prevents using the client without using guest login and without token.
This commit is contained in:
parent
b116457796
commit
9cdd68abed
@ -10,7 +10,7 @@ Create a client using and request guest login.
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
let client = Client::new("https://ars.particify.de/api").expect("client created");
|
let client = Client::new("https://ars.particify.de/api").expect("client created");
|
||||||
client.guest_login().await;
|
let client = client.guest_login().await.expect("logged in");
|
||||||
```
|
```
|
||||||
|
|
||||||
### Request room information
|
### Request room information
|
||||||
|
@ -55,14 +55,12 @@ pub struct Cli {
|
|||||||
async fn main() -> Result<(), ()> {
|
async fn main() -> Result<(), ()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let mut client = match Client::new(&cli.url) {
|
let client = match Client::new(&cli.url) {
|
||||||
Ok(client) => client,
|
Ok(client) => client,
|
||||||
Err(_) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if client.guest_login().await.is_err() {
|
let client = client.guest_login().await.map_err(|_| ())?;
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (tx, rx) = channel::<Feedback>(10);
|
let (tx, rx) = channel::<Feedback>(10);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
@ -199,10 +200,14 @@ impl Display for ClientError {
|
|||||||
|
|
||||||
impl error::Error for ClientError {}
|
impl error::Error for ClientError {}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct LoggedIn;
|
||||||
|
pub struct LoggedOut;
|
||||||
|
|
||||||
|
pub struct Client<State = LoggedOut> {
|
||||||
api_url: String,
|
api_url: String,
|
||||||
http_client: reqwest::Client,
|
http_client: reqwest::Client,
|
||||||
token: Option<String>,
|
token: Option<String>,
|
||||||
|
state: PhantomData<State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@ -216,10 +221,13 @@ impl Client {
|
|||||||
api_url: api_url.to_string(),
|
api_url: api_url.to_string(),
|
||||||
http_client: client,
|
http_client: client,
|
||||||
token: None,
|
token: None,
|
||||||
|
state: PhantomData::<LoggedOut>,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn guest_login(&mut self) -> Result<(), ClientError> {
|
impl Client<LoggedOut> {
|
||||||
|
pub async fn guest_login(self) -> Result<Client<LoggedIn>, ClientError> {
|
||||||
match self
|
match self
|
||||||
.http_client
|
.http_client
|
||||||
.post(format!("{}/auth/login/guest", self.api_url))
|
.post(format!("{}/auth/login/guest", self.api_url))
|
||||||
@ -227,15 +235,28 @@ impl Client {
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(res) => match res.json::<LoginResponse>().await {
|
Ok(res) => match res.json::<LoginResponse>().await {
|
||||||
Ok(res) => {
|
Ok(res) => Ok(Client {
|
||||||
self.token = Some(res.token);
|
api_url: self.api_url,
|
||||||
Ok(())
|
http_client: self.http_client,
|
||||||
}
|
token: Some(res.token),
|
||||||
|
state: PhantomData::<LoggedIn>,
|
||||||
|
}),
|
||||||
Err(_) => Err(LoginError),
|
Err(_) => Err(LoginError),
|
||||||
},
|
},
|
||||||
Err(_) => Err(ConnectionError),
|
Err(_) => Err(ConnectionError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client<LoggedIn> {
|
||||||
|
pub fn logout(self) -> Client<LoggedOut> {
|
||||||
|
Client {
|
||||||
|
api_url: self.api_url,
|
||||||
|
http_client: self.http_client,
|
||||||
|
token: None,
|
||||||
|
state: PhantomData::<LoggedOut>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_room_info(&self, short_id: &str) -> Result<RoomInfo, ClientError> {
|
pub async fn get_room_info(&self, short_id: &str) -> Result<RoomInfo, ClientError> {
|
||||||
let token = self.token.as_ref().unwrap();
|
let token = self.token.as_ref().unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user