mastodon API rust lib elefren, fixed and updated. and also all ASYNC! NB. most examples are now wrong.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
elefren-fork/src/macros.rs

238 lines
7.6 KiB

macro_rules! methods {
($($method:ident,)+) => {
$(
pub async fn $method<T: for<'de> serde::Deserialize<'de>>(&self, url: String)
-> Result<T>
{
log::trace!("{} {}", stringify!($method), url);
let response = self.send(
self.http_client.$method(&url)
).await?;
deserialise_response(response).await
}
)+
};
}
macro_rules! route_v1_paged {
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
"# Errors\n",
"If `access_token` is not set.",
),
pub async fn $name<'a>(&'a self) -> Result<Page<'a, $ret>> {
let url = self.route(concat!("/api/v1/", $url));
let response = self.send(
self.http_client.$method(&url)
).await?;
Page::new(self, response).await
}
}
};
((get ($($(#[$m:meta])* $param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `get /api/v1/", $url, "` with query params\n",
"# Errors\n",
"If `access_token` is not set.",
),
pub async fn $name<'a, 'b>(&'b self, $($param: $typ,)*) -> Result<Page<'b, $ret>> {
use serde_urlencoded;
use serde::Serialize;
#[derive(Serialize)]
struct Data<'a> {
$(
$(
#[$m]
)*
$param: $typ,
)*
#[serde(skip)]
_marker: ::std::marker::PhantomData<&'a ()>,
}
let qs_data = Data {
$(
$param,
)*
_marker: ::std::marker::PhantomData,
};
let qs = serde_urlencoded::to_string(&qs_data)?;
let url = format!(concat!("/api/v1/", $url, "?{}"), &qs);
let response = self.send(
self.http_client.get(&url)
).await?;
Page::new(self, response).await
}
}
};
}
macro_rules! route_v2 {
((get ($($(#[$m:meta])* $param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `get /api/v2/",$url,"`\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
use serde_urlencoded;
use serde::Serialize;
#[derive(Serialize)]
struct Data<'a> {
$(
$(
#[$m]
)*
$param: $typ,
)*
#[serde(skip)]
_marker: ::std::marker::PhantomData<&'a ()>,
}
let qs_data = Data {
$(
$param,
)*
_marker: ::std::marker::PhantomData,
};
let qs = serde_urlencoded::to_string(&qs_data)?;
let url = format!(concat!("/api/v2/", $url, "?{}"), &qs);
self.get(self.route(&url)).await
}
}
};
}
macro_rules! route_v1 {
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `get /api/v1/", $url, "`\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
use serde_urlencoded;
use serde::Serialize;
#[derive(Serialize)]
struct Data<'a> {
$(
$param: $typ,
)*
#[serde(skip)]
_marker: ::std::marker::PhantomData<&'a ()>,
}
let qs_data = Data {
$(
$param,
)*
_marker: ::std::marker::PhantomData,
};
let qs = serde_urlencoded::to_string(&qs_data)?;
let url = format!(concat!("/api/v1/", $url, "?{}"), &qs);
self.get(self.route(&url)).await
}
}
};
(($method:ident ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
let form_data = serde_json::json!({
$(
stringify!($param): $param,
)*
});
let response = self.send(
self.http_client.$method(&self.route(concat!("/api/v1/", $url)))
.json(&form_data)
).await?;
let status = response.status().clone();
if status.is_client_error() {
return Err(Error::Client(status));
} else if status.is_server_error() {
return Err(Error::Server(status));
}
deserialise_response(response).await
}
}
};
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name(&self) -> Result<$ret> {
self.$method(self.route(concat!("/api/v1/", $url))).await
}
}
};
}
macro_rules! route_v1_id {
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name(&self, id: &str) -> Result<$ret> {
self.$method(self.route(&format!(concat!("/api/v1/", $url), id))).await
}
}
}
}
macro_rules! route_v1_paged_id {
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
doc_comment::doc_comment! {
concat!(
"Equivalent to `", stringify!($method), " /api/v1/", $url, "` with ID\n",
"# Errors\n",
"If `access_token` is not set."
),
pub async fn $name<'a>(&'a self, id: &str) -> Result<Page<'a, $ret>> {
let url = self.route(&format!(concat!("/api/v1/", $url), id));
let response = self.send(
self.http_client.$method(&url)
).await?;
Page::new(self, response).await
}
}
};
}