use crate::{
errors::Result,
model::{ApplicationInformation, CreatePasteRequest, CreatedPaste, Metadata, Paste},
};
use reqwest::{Client, IntoUrl, Request, Url};
use serde::de::DeserializeOwned;
#[derive(Clone)]
pub struct UnauthenticatedClient {
client: Client,
host: Url,
}
impl UnauthenticatedClient {
pub fn new(host: impl IntoUrl) -> Result<Self> {
Ok(Self {
client: Default::default(),
host: host.into_url()?,
})
}
pub async fn application_information(&self) -> Result<ApplicationInformation> {
let r = self.client.get(self.host.join("/api/v2/info")?).build()?;
req_body(&self.client, r).await
}
pub async fn paste(&self, id: &str) -> Result<Paste> {
let r = self
.client
.get(self.host.join(&format!("/api/v2/pastes/{id}"))?)
.build()?;
req_body(&self.client, r).await
}
pub async fn create_paste(
&self,
content: impl Into<String>,
metadata: Option<Metadata>,
) -> Result<CreatedPaste> {
let r = self
.client
.post(self.host.join("/api/v2/pastes")?)
.json(&CreatePasteRequest {
content: content.into(),
metadata,
})
.build()?;
req_body(&self.client, r).await
}
pub fn authenticate(self, token: impl Into<String>) -> AuthenticatedClient {
AuthenticatedClient {
client: self,
token: token.into(),
}
}
}
#[derive(Clone)]
pub struct AuthenticatedClient {
client: UnauthenticatedClient,
token: String,
}
impl AuthenticatedClient {
pub fn inner(&self) -> &UnauthenticatedClient {
&self.client
}
pub async fn update_paste(
&self,
id: &str,
content: impl Into<String>,
metadata: Option<Metadata>,
) -> Result<()> {
let r = self
.client
.client
.patch(self.client.host.join(&format!("/api/v2/pastes/{id}"))?)
.json(&CreatePasteRequest {
content: content.into(),
metadata,
})
.bearer_auth(&self.token)
.build()?;
req(&self.client.client, r).await
}
pub async fn delete_paste(&self, id: &str) -> Result<()> {
let r = self
.client
.client
.delete(self.client.host.join(&format!("/api/v2/pastes/{id}"))?)
.bearer_auth(&self.token)
.build()?;
req(&self.client.client, r).await
}
}
async fn req_body<T: DeserializeOwned>(client: &Client, req: Request) -> Result<T> {
let res = client
.execute(req)
.await?
.error_for_status()?
.json()
.await?;
Ok(res)
}
async fn req(client: &Client, req: Request) -> Result<()> {
client.execute(req).await?.error_for_status()?;
Ok(())
}