2022-11-27 14:44:43 +00:00
|
|
|
macro_rules! methods {
|
2022-12-07 20:58:28 +00:00
|
|
|
($($method:ident and $method_with_call_id:ident,)+) => {
|
2022-11-27 14:44:43 +00:00
|
|
|
$(
|
2022-12-07 20:58:28 +00:00
|
|
|
doc_comment! {
|
|
|
|
concat!("Make a ", stringify!($method), " API request, and deserialize the result into T"),
|
|
|
|
async fn $method<T: for<'de> serde::Deserialize<'de> + serde::Serialize>(&self, url: impl AsRef<str>) -> Result<T>
|
|
|
|
{
|
|
|
|
let call_id = uuid::Uuid::new_v4();
|
|
|
|
self.$method_with_call_id(url, call_id).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Make a ", stringify!($method), " API request, and deserialize the result into T.\n\n",
|
|
|
|
"Logging will use the provided UUID, rather than generating one before making the request.",
|
|
|
|
),
|
|
|
|
async fn $method_with_call_id<T: for<'de> serde::Deserialize<'de> + serde::Serialize>(&self, url: impl AsRef<str>, call_id: Uuid) -> Result<T>
|
|
|
|
{
|
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
use log::{debug, as_debug};
|
2022-12-07 20:58:28 +00:00
|
|
|
|
|
|
|
let url = url.as_ref();
|
|
|
|
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.$method(url)).header("Accept", "application/json").send().await?;
|
|
|
|
read_response(response).await
|
2022-12-07 20:58:28 +00:00
|
|
|
}
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
)+
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! paged_routes {
|
|
|
|
|
|
|
|
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `", stringify!($method), " /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set.",
|
|
|
|
"\n",
|
|
|
|
"```no_run",
|
2022-12-22 18:19:49 +00:00
|
|
|
"use mastodon_async::prelude::*;\n",
|
2022-11-29 23:50:29 +00:00
|
|
|
"let data = Data::default();\n",
|
2022-11-27 14:44:43 +00:00
|
|
|
"let client = Mastodon::from(data);\n",
|
|
|
|
"client.", stringify!($name), "();\n",
|
|
|
|
"```"
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name(&self) -> Result<Page<$ret>> {
|
2022-12-23 15:09:33 +00:00
|
|
|
use log::{debug, as_debug};
|
2022-11-27 14:44:43 +00:00
|
|
|
let url = self.route(concat!("/api/v1/", $url));
|
2022-12-07 20:58:28 +00:00
|
|
|
let call_id = uuid::Uuid::new_v4();
|
|
|
|
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.$method(&url)).header("Accept", "application/json").send().await?;
|
|
|
|
|
|
|
|
Page::new(self.clone(), response, call_id).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
paged_routes!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
((get ($($(#[$m:meta])* $param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `get /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set."
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name<'a>(&self, $($param: $typ,)*) -> Result<Page<$ret>> {
|
2022-11-27 14:44:43 +00:00
|
|
|
use serde_urlencoded;
|
2022-12-23 15:09:33 +00:00
|
|
|
use log::{debug, as_debug};
|
2022-12-07 20:58:28 +00:00
|
|
|
|
|
|
|
let call_id = uuid::Uuid::new_v4();
|
2022-11-27 14:44:43 +00:00
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct Data<'a> {
|
|
|
|
$(
|
|
|
|
$(
|
|
|
|
#[$m]
|
|
|
|
)*
|
|
|
|
$param: $typ,
|
|
|
|
)*
|
|
|
|
#[serde(skip)]
|
|
|
|
_marker: ::std::marker::PhantomData<&'a ()>,
|
|
|
|
}
|
|
|
|
|
2022-12-27 14:55:36 +00:00
|
|
|
#[allow(clippy::redundant_field_names)]
|
2022-11-27 14:44:43 +00:00
|
|
|
let qs_data = Data {
|
|
|
|
$(
|
|
|
|
$param: $param,
|
|
|
|
)*
|
|
|
|
_marker: ::std::marker::PhantomData,
|
|
|
|
};
|
|
|
|
|
|
|
|
let qs = serde_urlencoded::to_string(&qs_data)?;
|
|
|
|
|
|
|
|
let url = format!(concat!("/api/v1/", $url, "?{}"), &qs);
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
debug!(url = url, method = "get", call_id = as_debug!(call_id); "making API request");
|
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.get(&url)).header("Accept", "application/json").send().await?;
|
2022-11-27 14:44:43 +00:00
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
Page::new(self.clone(), response, call_id).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
paged_routes!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
() => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! route_v2 {
|
|
|
|
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `get /api/v2/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set."
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
2022-11-27 14:44:43 +00:00
|
|
|
use serde_urlencoded;
|
2022-12-07 20:58:28 +00:00
|
|
|
use log::{debug, as_serde};
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
let call_id = Uuid::new_v4();
|
2022-11-27 14:44:43 +00:00
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct Data<'a> {
|
|
|
|
$(
|
|
|
|
$param: $typ,
|
|
|
|
)*
|
|
|
|
#[serde(skip)]
|
|
|
|
_marker: ::std::marker::PhantomData<&'a ()>,
|
|
|
|
}
|
|
|
|
|
2022-12-27 14:55:36 +00:00
|
|
|
#[allow(clippy::redundant_field_names)]
|
2022-11-27 14:44:43 +00:00
|
|
|
let qs_data = Data {
|
|
|
|
$(
|
|
|
|
$param: $param,
|
|
|
|
)*
|
|
|
|
_marker: ::std::marker::PhantomData,
|
|
|
|
};
|
|
|
|
|
|
|
|
let qs = serde_urlencoded::to_string(&qs_data)?;
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
debug!(query_string_data = as_serde!(qs_data); "URL-encoded data to be sent in API request");
|
|
|
|
|
2022-11-27 14:44:43 +00:00
|
|
|
let url = format!(concat!("/api/v2/", $url, "?{}"), &qs);
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
self.get_with_call_id(self.route(&url), call_id).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
route_v2!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
2022-12-25 12:01:41 +00:00
|
|
|
((post multipart with description ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `post /api/v2/",
|
|
|
|
$url,
|
|
|
|
"`, with a description/alt-text.",
|
|
|
|
"\n# Errors\nIf `access_token` is not set."),
|
|
|
|
pub async fn $name(&self $(, $param: $typ)*, description: Option<String>) -> Result<$ret> {
|
2022-12-26 16:19:54 +00:00
|
|
|
use reqwest::multipart::Form;
|
|
|
|
use log::{debug, as_debug};
|
2022-12-25 12:01:41 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
let call_id = Uuid::new_v4();
|
|
|
|
|
|
|
|
let form_data = Form::new()
|
|
|
|
$(
|
2022-12-28 12:58:40 +00:00
|
|
|
.part(stringify!($param), Self::get_form_part($param)?)
|
2022-12-25 12:01:41 +00:00
|
|
|
)*;
|
|
|
|
|
|
|
|
let form_data = if let Some(description) = description {
|
|
|
|
form_data.text("description", description)
|
|
|
|
} else { form_data };
|
|
|
|
|
|
|
|
let url = &self.route(concat!("/api/v2/", $url));
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
url = url, method = stringify!($method),
|
|
|
|
multipart_form_data = as_debug!(form_data), call_id = as_debug!(call_id);
|
|
|
|
"making API request"
|
|
|
|
);
|
|
|
|
|
|
|
|
let response = self.authenticated(self.client.post(url))
|
|
|
|
.multipart(form_data)
|
|
|
|
.header("Accept", "application/json")
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
read_response(response).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
route_v2! { $($rest)* }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
((post multipart ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `post /api/v2/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set."),
|
|
|
|
pub async fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
2022-12-26 16:19:54 +00:00
|
|
|
use reqwest::multipart::Form;
|
|
|
|
use log::{debug, as_debug};
|
2022-12-23 15:09:33 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
2022-12-26 16:19:54 +00:00
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
let call_id = Uuid::new_v4();
|
|
|
|
|
|
|
|
let form_data = Form::new()
|
|
|
|
$(
|
2022-12-28 12:58:40 +00:00
|
|
|
.part(stringify!($param), Self::get_form_part($param)?)
|
2022-12-23 15:09:33 +00:00
|
|
|
)*;
|
|
|
|
|
|
|
|
let url = &self.route(concat!("/api/v2/", $url));
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
url = url, method = stringify!($method),
|
|
|
|
multipart_form_data = as_debug!(form_data), call_id = as_debug!(call_id);
|
|
|
|
"making API request"
|
|
|
|
);
|
|
|
|
|
|
|
|
let response = self.authenticated(self.client.post(url))
|
|
|
|
.multipart(form_data)
|
|
|
|
.header("Accept", "application/json")
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
read_response(response).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-25 11:48:24 +00:00
|
|
|
route_v2!{$($rest)*}
|
2022-12-23 15:09:33 +00:00
|
|
|
};
|
2022-11-27 14:44:43 +00:00
|
|
|
() => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! route {
|
|
|
|
|
|
|
|
((post multipart ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `post /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set."),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
2022-12-26 16:19:54 +00:00
|
|
|
use reqwest::multipart::Form;
|
|
|
|
use log::{debug, as_debug};
|
2022-12-07 20:58:28 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
2022-12-26 16:19:54 +00:00
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
let call_id = Uuid::new_v4();
|
2022-11-27 14:44:43 +00:00
|
|
|
|
|
|
|
let form_data = Form::new()
|
|
|
|
$(
|
2022-12-28 12:58:40 +00:00
|
|
|
.part(stringify!($param), Self::get_form_part($param)?)
|
2022-11-27 14:44:43 +00:00
|
|
|
)*;
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
let url = &self.route(concat!("/api/v1/", $url));
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
url = url, method = stringify!($method),
|
|
|
|
multipart_form_data = as_debug!(form_data), call_id = as_debug!(call_id);
|
|
|
|
"making API request"
|
|
|
|
);
|
|
|
|
|
2022-12-18 21:03:46 +00:00
|
|
|
let response = self.authenticated(self.client.post(url))
|
2022-12-05 13:52:48 +00:00
|
|
|
.multipart(form_data)
|
2022-12-23 15:09:33 +00:00
|
|
|
.header("Accept", "application/json")
|
2022-12-05 13:52:48 +00:00
|
|
|
.send()
|
|
|
|
.await?;
|
2022-11-27 14:44:43 +00:00
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
read_response(response).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
route!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
2022-12-25 12:01:41 +00:00
|
|
|
((post multipart with description ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `post /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`, with a description/alt-text.",
|
|
|
|
"\n# Errors\nIf `access_token` is not set."),
|
|
|
|
pub async fn $name(&self $(, $param: $typ)*, description: Option<String>) -> Result<$ret> {
|
2022-12-26 16:19:54 +00:00
|
|
|
use reqwest::multipart::Form;
|
|
|
|
use log::{debug, as_debug};
|
2022-12-25 12:01:41 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
2022-12-26 16:19:54 +00:00
|
|
|
|
2022-12-25 12:01:41 +00:00
|
|
|
let call_id = Uuid::new_v4();
|
|
|
|
|
|
|
|
let form_data = Form::new()
|
|
|
|
$(
|
2022-12-28 12:58:40 +00:00
|
|
|
.part(stringify!($param), Self::get_form_part($param)?)
|
2022-12-25 12:01:41 +00:00
|
|
|
)*;
|
|
|
|
|
|
|
|
let form_data = if let Some(description) = description {
|
|
|
|
form_data.text("description", description)
|
|
|
|
} else { form_data };
|
|
|
|
|
|
|
|
let url = &self.route(concat!("/api/v1/", $url));
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
url = url, method = stringify!($method),
|
|
|
|
multipart_form_data = as_debug!(form_data), call_id = as_debug!(call_id);
|
|
|
|
"making API request"
|
|
|
|
);
|
|
|
|
|
|
|
|
let response = self.authenticated(self.client.post(url))
|
|
|
|
.multipart(form_data)
|
|
|
|
.header("Accept", "application/json")
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
read_response(response).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
route! { $($rest)* }
|
|
|
|
};
|
2022-11-27 14:44:43 +00:00
|
|
|
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `get /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set."
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
2022-11-27 14:44:43 +00:00
|
|
|
use serde_urlencoded;
|
2022-12-07 20:58:28 +00:00
|
|
|
use log::{debug, as_serde};
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
let call_id = Uuid::new_v4();
|
2022-11-27 14:44:43 +00:00
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct Data<'a> {
|
|
|
|
$(
|
|
|
|
$param: $typ,
|
|
|
|
)*
|
|
|
|
#[serde(skip)]
|
|
|
|
_marker: ::std::marker::PhantomData<&'a ()>,
|
|
|
|
}
|
|
|
|
|
2022-12-27 14:55:36 +00:00
|
|
|
#[allow(clippy::redundant_field_names)]
|
2022-11-27 14:44:43 +00:00
|
|
|
let qs_data = Data {
|
|
|
|
$(
|
|
|
|
$param: $param,
|
|
|
|
)*
|
|
|
|
_marker: ::std::marker::PhantomData,
|
|
|
|
};
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
|
2022-11-27 14:44:43 +00:00
|
|
|
let qs = serde_urlencoded::to_string(&qs_data)?;
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
debug!(query_string_data = as_serde!(qs_data); "URL-encoded data to be sent in API request");
|
|
|
|
|
2022-11-27 14:44:43 +00:00
|
|
|
let url = format!(concat!("/api/v1/", $url, "?{}"), &qs);
|
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
self.get_with_call_id(self.route(&url), call_id).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
route!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
(($method:ident ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `", stringify!($method), " /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set.",
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
2022-12-23 15:09:33 +00:00
|
|
|
use log::{debug, as_debug, as_serde};
|
2022-12-07 20:58:28 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
let call_id = Uuid::new_v4();
|
2022-11-27 14:44:43 +00:00
|
|
|
|
|
|
|
let form_data = json!({
|
|
|
|
$(
|
|
|
|
stringify!($param): $param,
|
|
|
|
)*
|
|
|
|
});
|
2022-12-18 21:03:46 +00:00
|
|
|
let url = &self.route(concat!("/api/v1/", $url));
|
2022-12-07 20:58:28 +00:00
|
|
|
debug!(
|
2022-12-18 21:03:46 +00:00
|
|
|
url = url.as_str(), method = stringify!($method),
|
2022-12-07 20:58:28 +00:00
|
|
|
call_id = as_debug!(call_id),
|
|
|
|
form_data = as_serde!(&form_data);
|
|
|
|
"making API request"
|
|
|
|
);
|
2022-11-27 14:44:43 +00:00
|
|
|
|
2022-12-18 21:03:46 +00:00
|
|
|
let response = self.authenticated(self.client.$method(url))
|
2022-12-05 13:52:48 +00:00
|
|
|
.json(&form_data)
|
2022-12-23 15:09:33 +00:00
|
|
|
.header("Accept", "application/json")
|
2022-12-05 13:52:48 +00:00
|
|
|
.send()
|
|
|
|
.await?;
|
2022-11-27 14:44:43 +00:00
|
|
|
|
2022-12-23 15:09:33 +00:00
|
|
|
read_response(response).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
route!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `", stringify!($method), " /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set.",
|
|
|
|
"\n",
|
|
|
|
"```no_run",
|
2022-12-22 18:19:49 +00:00
|
|
|
"use mastodon_async::prelude::*;\n",
|
2022-11-29 23:50:29 +00:00
|
|
|
"let data = Data::default();\n",
|
2022-11-27 14:44:43 +00:00
|
|
|
"let client = Mastodon::from(data);\n",
|
|
|
|
"client.", stringify!($name), "();\n",
|
|
|
|
"```"
|
|
|
|
),
|
2022-12-05 13:52:48 +00:00
|
|
|
pub async fn $name(&self) -> Result<$ret> {
|
|
|
|
self.$method(self.route(concat!("/api/v1/", $url))).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
route!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
() => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! route_id {
|
|
|
|
|
2023-01-21 19:36:45 +00:00
|
|
|
($(($method:ident) $name:ident[$id_type:ty]: $url:expr => $ret:ty,)*) => {
|
2022-11-27 14:44:43 +00:00
|
|
|
$(
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `", stringify!($method), " /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set.",
|
|
|
|
"\n",
|
|
|
|
"```no_run",
|
2022-12-22 18:19:49 +00:00
|
|
|
"use mastodon_async::prelude::*;\n",
|
2022-11-29 23:50:29 +00:00
|
|
|
"let data = Data::default();\n",
|
2022-11-27 14:44:43 +00:00
|
|
|
"let client = Mastodon::from(data);\n",
|
|
|
|
"client.", stringify!($name), "(\"42\");\n",
|
|
|
|
"# Ok(())\n",
|
|
|
|
"# }\n",
|
|
|
|
"```"
|
|
|
|
),
|
2023-01-21 19:36:45 +00:00
|
|
|
pub async fn $name(&self, id: &$id_type) -> Result<$ret> {
|
2022-12-05 13:52:48 +00:00
|
|
|
self.$method(self.route(&format!(concat!("/api/v1/", $url), id))).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
macro_rules! paged_routes_with_id {
|
|
|
|
|
|
|
|
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
"Equivalent to `", stringify!($method), " /api/v1/",
|
|
|
|
$url,
|
|
|
|
"`\n# Errors\nIf `access_token` is not set.",
|
|
|
|
"\n",
|
|
|
|
"```no_run",
|
2022-12-22 18:19:49 +00:00
|
|
|
"use mastodon_async::prelude::*;\n",
|
2022-11-29 23:50:29 +00:00
|
|
|
"let data = Data::default();",
|
2022-11-27 14:44:43 +00:00
|
|
|
"let client = Mastodon::from(data);\n",
|
|
|
|
"client.", stringify!($name), "(\"some-id\");\n",
|
|
|
|
"```"
|
|
|
|
),
|
2023-01-09 13:04:07 +00:00
|
|
|
pub async fn $name(&self, id: impl AsRef<str>) -> Result<Page<$ret>> {
|
2022-12-23 15:09:33 +00:00
|
|
|
use log::{debug, as_debug};
|
2022-12-07 20:58:28 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
let call_id = Uuid::new_v4();
|
2023-01-09 13:04:07 +00:00
|
|
|
let url = self.route(&format!(concat!("/api/v1/", $url), id.as_ref()));
|
2022-11-27 14:44:43 +00:00
|
|
|
|
2022-12-07 20:58:28 +00:00
|
|
|
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.$method(&url)).header("Accept", "application/json").send().await?;
|
|
|
|
Page::new(self.clone(), response, call_id).await
|
2022-11-27 14:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
paged_routes_with_id!{$($rest)*}
|
|
|
|
};
|
|
|
|
|
|
|
|
() => {}
|
|
|
|
}
|
2022-12-18 22:30:23 +00:00
|
|
|
|
|
|
|
macro_rules! streaming {
|
2022-12-22 17:28:08 +00:00
|
|
|
($desc:tt $fn_name:ident@$stream:literal, $($rest:tt)*) => {
|
2022-12-18 23:00:58 +00:00
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
$desc,
|
|
|
|
"\n\nExample:\n\n",
|
|
|
|
"
|
2022-12-22 18:19:49 +00:00
|
|
|
use mastodon_async::prelude::*;
|
|
|
|
use mastodon_async::entities::event::Event;
|
2022-12-18 22:30:23 +00:00
|
|
|
use futures_util::{pin_mut, StreamExt, TryStreamExt};
|
|
|
|
|
|
|
|
tokio_test::block_on(async {
|
|
|
|
let data = Data::default();
|
|
|
|
let client = Mastodon::from(data);
|
|
|
|
let stream = client.",
|
|
|
|
stringify!($fn_name),
|
|
|
|
"().await.unwrap();
|
|
|
|
stream.try_for_each(|event| async move {
|
|
|
|
match event {
|
|
|
|
Event::Update(ref status) => { /* .. */ },
|
|
|
|
Event::Notification(ref notification) => { /* .. */ },
|
|
|
|
Event::Delete(ref id) => { /* .. */ },
|
|
|
|
Event::FiltersChanged => { /* .. */ },
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}).await.unwrap();
|
|
|
|
});"
|
2022-12-18 23:00:58 +00:00
|
|
|
),
|
2023-02-13 16:54:49 +00:00
|
|
|
pub async fn $fn_name(&self) -> Result<impl TryStream<Ok=(Event, Mastodon), Error=Error> + '_> {
|
|
|
|
use $crate::event_stream::event_stream;
|
2022-12-22 17:28:08 +00:00
|
|
|
let url = self.route(&format!("/api/v1/streaming/{}", $stream));
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.get(&url)).header("Accept", "application/json").send().await?;
|
2022-12-18 23:00:58 +00:00
|
|
|
debug!(
|
|
|
|
status = log_serde!(response Status), url = &url,
|
|
|
|
headers = log_serde!(response Headers);
|
|
|
|
"received API response"
|
|
|
|
);
|
2022-12-23 15:09:33 +00:00
|
|
|
let status = response.status();
|
|
|
|
if status.is_success() {
|
2023-02-13 16:54:49 +00:00
|
|
|
Ok(event_stream(response, url, self))
|
2022-12-23 15:09:33 +00:00
|
|
|
} else {
|
|
|
|
let response = response.json().await?;
|
|
|
|
Err(Error::Api{ status, response })
|
|
|
|
}
|
2022-12-18 23:00:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
streaming! { $($rest)* }
|
|
|
|
};
|
2022-12-22 17:28:08 +00:00
|
|
|
($desc:tt $fn_name:ident($param:ident: $param_type:ty, like $param_doc_val:literal)@$stream:literal, $($rest:tt)*) => {
|
2022-12-18 23:00:58 +00:00
|
|
|
doc_comment! {
|
|
|
|
concat!(
|
|
|
|
$desc,
|
|
|
|
"\n\nExample:\n\n",
|
|
|
|
"
|
2022-12-22 18:19:49 +00:00
|
|
|
use mastodon_async::prelude::*;
|
|
|
|
use mastodon_async::entities::event::Event;
|
2022-12-18 23:00:58 +00:00
|
|
|
use futures_util::{pin_mut, StreamExt, TryStreamExt};
|
|
|
|
|
|
|
|
tokio_test::block_on(async {
|
|
|
|
let data = Data::default();
|
|
|
|
let client = Mastodon::from(data);
|
|
|
|
let stream = client.",
|
|
|
|
stringify!($fn_name),
|
|
|
|
"(",
|
|
|
|
$param_doc_val,
|
|
|
|
").await.unwrap();
|
|
|
|
stream.try_for_each(|event| async move {
|
|
|
|
match event {
|
|
|
|
Event::Update(ref status) => { /* .. */ },
|
|
|
|
Event::Notification(ref notification) => { /* .. */ },
|
|
|
|
Event::Delete(ref id) => { /* .. */ },
|
|
|
|
Event::FiltersChanged => { /* .. */ },
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}).await.unwrap();
|
|
|
|
});"
|
|
|
|
),
|
2023-02-13 16:54:49 +00:00
|
|
|
pub async fn $fn_name(&self, $param: $param_type) -> Result<impl TryStream<Ok=(Event, Mastodon), Error=Error> + '_> {
|
|
|
|
use $crate::event_stream::event_stream;
|
2022-12-18 23:00:58 +00:00
|
|
|
let mut url: Url = self.route(concat!("/api/v1/streaming/", stringify!($stream))).parse()?;
|
|
|
|
url.query_pairs_mut().append_pair(stringify!($param), $param.as_ref());
|
|
|
|
let url = url.to_string();
|
2022-12-23 15:09:33 +00:00
|
|
|
let response = self.authenticated(self.client.get(url.as_str())).header("Accept", "application/json").send().await?;
|
2022-12-18 23:00:58 +00:00
|
|
|
debug!(
|
|
|
|
status = log_serde!(response Status), url = as_debug!(url),
|
|
|
|
headers = log_serde!(response Headers);
|
|
|
|
"received API response"
|
|
|
|
);
|
2022-12-23 15:09:33 +00:00
|
|
|
let status = response.status();
|
|
|
|
if status.is_success() {
|
2023-02-13 16:54:49 +00:00
|
|
|
Ok(event_stream(response, url, self))
|
2022-12-23 15:09:33 +00:00
|
|
|
} else {
|
|
|
|
let response = response.json().await?;
|
|
|
|
Err(Error::Api{ status, response })
|
|
|
|
}
|
2022-12-18 22:30:23 +00:00
|
|
|
}
|
2022-12-18 23:00:58 +00:00
|
|
|
}
|
|
|
|
streaming! { $($rest)* }
|
2022-12-18 22:30:23 +00:00
|
|
|
};
|
2022-12-18 23:00:58 +00:00
|
|
|
() => {}
|
2022-12-18 22:30:23 +00:00
|
|
|
}
|