removed the trait so it can be easier made async
This commit is contained in:
+107
-171
@@ -47,10 +47,10 @@
|
|||||||
//! let client = Mastodon::from(data);
|
//! let client = Mastodon::from(data);
|
||||||
//! for event in client.streaming_user()? {
|
//! for event in client.streaming_user()? {
|
||||||
//! match event {
|
//! match event {
|
||||||
//! Event::Update(ref status) => { /* .. */ },
|
//! Event::Update(ref status) => { /* .. */ }
|
||||||
//! Event::Notification(ref notification) => { /* .. */ },
|
//! Event::Notification(ref notification) => { /* .. */ }
|
||||||
//! Event::Delete(ref id) => { /* .. */ },
|
//! Event::Delete(ref id) => { /* .. */ }
|
||||||
//! Event::FiltersChanged => { /* .. */ },
|
//! Event::FiltersChanged => { /* .. */ }
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! # Ok(())
|
//! # Ok(())
|
||||||
@@ -69,28 +69,30 @@
|
|||||||
unused_import_braces,
|
unused_import_braces,
|
||||||
unused_qualifications
|
unused_qualifications
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(feature = "nightly", allow(broken_intra_doc_links))]
|
// #![cfg_attr(feature = "nightly", allow(broken_intra_doc_links))]
|
||||||
#![allow(broken_intra_doc_links)]
|
// #![allow(broken_intra_doc_links)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
use std::{borrow::Cow, io::BufRead, ops};
|
use std::{borrow::Cow, io::BufRead, ops};
|
||||||
|
use std::net::TcpStream;
|
||||||
|
|
||||||
use reqwest::blocking::{multipart, Client, RequestBuilder, Response};
|
pub use isolang::Language;
|
||||||
|
use reqwest::blocking::{Client, multipart, RequestBuilder, Response};
|
||||||
use tap_reader::Tap;
|
use tap_reader::Tap;
|
||||||
|
use tungstenite::stream::MaybeTlsStream;
|
||||||
|
|
||||||
use crate::{entities::prelude::*, page::Page};
|
use crate::{entities::prelude::*, page::Page};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
data::Data,
|
data::Data,
|
||||||
errors::{ApiError, Error, Result},
|
errors::{ApiError, Error, Result},
|
||||||
mastodon_client::{MastodonClient, MastodonUnauthenticated},
|
// mastodon_client::{MastodonClient, MastodonUnauthenticated},
|
||||||
media_builder::MediaBuilder,
|
media_builder::MediaBuilder,
|
||||||
registration::Registration,
|
registration::Registration,
|
||||||
requests::{AddFilterRequest, AddPushRequest, StatusesRequest, UpdateCredsRequest, UpdatePushRequest},
|
requests::{AddFilterRequest, AddPushRequest, StatusesRequest, UpdateCredsRequest, UpdatePushRequest},
|
||||||
status_builder::{NewStatus, StatusBuilder},
|
status_builder::{NewStatus, StatusBuilder},
|
||||||
};
|
};
|
||||||
pub use isolang::Language;
|
|
||||||
use tungstenite::stream::MaybeTlsStream;
|
|
||||||
use std::net::TcpStream;
|
|
||||||
|
|
||||||
/// Registering your App
|
/// Registering your App
|
||||||
pub mod apps;
|
pub mod apps;
|
||||||
@@ -117,22 +119,27 @@ pub mod scopes;
|
|||||||
pub mod status_builder;
|
pub mod status_builder;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
/// Automatically import the things you need
|
/// Automatically import the things you need
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
scopes::Scopes, Data, Mastodon, MastodonClient, NewStatus, Registration, StatusBuilder, StatusesRequest,
|
Data, Mastodon, NewStatus, Registration, scopes::Scopes, StatusBuilder, StatusesRequest,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// type Stream = EventReader<WebSocket>;
|
||||||
|
|
||||||
/// Your mastodon application client, handles all requests to and from Mastodon.
|
/// Your mastodon application client, handles all requests to and from Mastodon.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Mastodon {
|
pub struct Mastodon {
|
||||||
|
|
||||||
client: Client,
|
client: Client,
|
||||||
/// Raw data about your mastodon instance.
|
/// Raw data about your mastodon instance.
|
||||||
pub data: Data,
|
pub data: Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mastodon {
|
impl Mastodon {
|
||||||
|
|
||||||
methods![get, post, delete,];
|
methods![get, post, delete,];
|
||||||
|
|
||||||
fn route(&self, url: &str) -> String {
|
fn route(&self, url: &str) -> String {
|
||||||
@@ -154,79 +161,70 @@ impl From<Data> for Mastodon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MastodonClient for Mastodon {
|
type MastodonStream = EventReader<WebSocket>;
|
||||||
type Stream = EventReader<WebSocket>;
|
|
||||||
|
|
||||||
paged_routes! {
|
impl Mastodon {
|
||||||
(get) favourites: "favourites" => Status,
|
route_v1_paged!((get) favourites: "favourites" => Status);
|
||||||
(get) blocks: "blocks" => Account,
|
route_v1_paged!((get) blocks: "blocks" => Account);
|
||||||
(get) domain_blocks: "domain_blocks" => String,
|
route_v1_paged!((get) domain_blocks: "domain_blocks" => String);
|
||||||
(get) follow_requests: "follow_requests" => Account,
|
route_v1_paged!((get) follow_requests: "follow_requests" => Account);
|
||||||
(get) get_home_timeline: "timelines/home" => Status,
|
route_v1_paged!((get) get_home_timeline: "timelines/home" => Status);
|
||||||
(get) get_local_timeline: "timelines/public?local=true" => Status,
|
route_v1_paged!((get) get_local_timeline: "timelines/public?local=true" => Status);
|
||||||
(get) get_federated_timeline: "timelines/public?local=false" => Status,
|
route_v1_paged!((get) get_federated_timeline: "timelines/public?local=false" => Status);
|
||||||
(get) get_emojis: "custom_emojis" => Emoji,
|
route_v1_paged!((get) get_emojis: "custom_emojis" => Emoji);
|
||||||
(get) mutes: "mutes" => Account,
|
route_v1_paged!((get) mutes: "mutes" => Account);
|
||||||
(get) notifications: "notifications" => Notification,
|
route_v1_paged!((get) notifications: "notifications" => Notification);
|
||||||
(get) reports: "reports" => Report,
|
route_v1_paged!((get) reports: "reports" => Report);
|
||||||
(get (q: &'a str, #[serde(skip_serializing_if = "Option::is_none")] limit: Option<u64>, following: bool,)) search_accounts: "accounts/search" => Account,
|
route_v1_paged!((get (q: &'a str, #[serde(skip_serializing_if = "Option::is_none")] limit: Option<u64>, following: bool,)) search_accounts: "accounts/search" => Account);
|
||||||
(get) get_endorsements: "endorsements" => Account,
|
route_v1_paged!((get) get_endorsements: "endorsements" => Account);
|
||||||
}
|
|
||||||
|
|
||||||
paged_routes_with_id! {
|
route_v1_paged_id!((get) followers: "accounts/{}/followers" => Account);
|
||||||
(get) followers: "accounts/{}/followers" => Account,
|
route_v1_paged_id!((get) following: "accounts/{}/following" => Account);
|
||||||
(get) following: "accounts/{}/following" => Account,
|
route_v1_paged_id!((get) reblogged_by: "statuses/{}/reblogged_by" => Account);
|
||||||
(get) reblogged_by: "statuses/{}/reblogged_by" => Account,
|
route_v1_paged_id!((get) favourited_by: "statuses/{}/favourited_by" => Account);
|
||||||
(get) favourited_by: "statuses/{}/favourited_by" => Account,
|
|
||||||
}
|
|
||||||
|
|
||||||
route! {
|
route_v1!((delete (domain: String,)) unblock_domain: "domain_blocks" => Empty);
|
||||||
(delete (domain: String,)) unblock_domain: "domain_blocks" => Empty,
|
route_v1!((get) instance: "instance" => Instance);
|
||||||
(get) instance: "instance" => Instance,
|
route_v1!((get) verify_credentials: "accounts/verify_credentials" => Account);
|
||||||
(get) verify_credentials: "accounts/verify_credentials" => Account,
|
route_v1!((post (account_id: &str, status_ids: Vec<&str>, comment: String,)) report: "reports" => Report);
|
||||||
(post (account_id: &str, status_ids: Vec<&str>, comment: String,)) report: "reports" => Report,
|
route_v1!((post (domain: String,)) block_domain: "domain_blocks" => Empty);
|
||||||
(post (domain: String,)) block_domain: "domain_blocks" => Empty,
|
route_v1!((post (id: &str,)) authorize_follow_request: "accounts/follow_requests/authorize" => Empty);
|
||||||
(post (id: &str,)) authorize_follow_request: "accounts/follow_requests/authorize" => Empty,
|
route_v1!((post (id: &str,)) reject_follow_request: "accounts/follow_requests/reject" => Empty);
|
||||||
(post (id: &str,)) reject_follow_request: "accounts/follow_requests/reject" => Empty,
|
route_v1!((get (q: &'a str, resolve: bool,)) search: "search" => SearchResult);
|
||||||
(get (q: &'a str, resolve: bool,)) search: "search" => SearchResult,
|
route_v1!((post (uri: Cow<'static, str>,)) follows: "follows" => Account);
|
||||||
(post (uri: Cow<'static, str>,)) follows: "follows" => Account,
|
route_v1!((post) clear_notifications: "notifications/clear" => Empty);
|
||||||
(post) clear_notifications: "notifications/clear" => Empty,
|
route_v1!((post (id: &str,)) dismiss_notification: "notifications/dismiss" => Empty);
|
||||||
(post (id: &str,)) dismiss_notification: "notifications/dismiss" => Empty,
|
route_v1!((get) get_push_subscription: "push/subscription" => Subscription);
|
||||||
(get) get_push_subscription: "push/subscription" => Subscription,
|
route_v1!((delete) delete_push_subscription: "push/subscription" => Empty);
|
||||||
(delete) delete_push_subscription: "push/subscription" => Empty,
|
route_v1!((get) get_filters: "filters" => Vec<Filter>);
|
||||||
(get) get_filters: "filters" => Vec<Filter>,
|
route_v1!((get) get_follow_suggestions: "suggestions" => Vec<Account>);
|
||||||
(get) get_follow_suggestions: "suggestions" => Vec<Account>,
|
|
||||||
}
|
|
||||||
|
|
||||||
route_v2! {
|
route_v2!((get (q: &'a str, resolve: bool,)) search_v2: "search" => SearchResultV2);
|
||||||
(get (q: &'a str, resolve: bool,)) search_v2: "search" => SearchResultV2,
|
|
||||||
}
|
|
||||||
|
|
||||||
route_id! {
|
route_v1_id!((get) get_account: "accounts/{}" => Account);
|
||||||
(get) get_account: "accounts/{}" => Account,
|
route_v1_id!((post) follow: "accounts/{}/follow" => Relationship);
|
||||||
(post) follow: "accounts/{}/follow" => Relationship,
|
route_v1_id!((post) unfollow: "accounts/{}/unfollow" => Relationship);
|
||||||
(post) unfollow: "accounts/{}/unfollow" => Relationship,
|
route_v1_id!((post) block: "accounts/{}/block" => Relationship);
|
||||||
(post) block: "accounts/{}/block" => Relationship,
|
route_v1_id!((post) unblock: "accounts/{}/unblock" => Relationship);
|
||||||
(post) unblock: "accounts/{}/unblock" => Relationship,
|
route_v1_id!((get) mute: "accounts/{}/mute" => Relationship);
|
||||||
(get) mute: "accounts/{}/mute" => Relationship,
|
route_v1_id!((get) unmute: "accounts/{}/unmute" => Relationship);
|
||||||
(get) unmute: "accounts/{}/unmute" => Relationship,
|
route_v1_id!((get) get_notification: "notifications/{}" => Notification);
|
||||||
(get) get_notification: "notifications/{}" => Notification,
|
route_v1_id!((get) get_status: "statuses/{}" => Status);
|
||||||
(get) get_status: "statuses/{}" => Status,
|
route_v1_id!((get) get_context: "statuses/{}/context" => Context);
|
||||||
(get) get_context: "statuses/{}/context" => Context,
|
route_v1_id!((get) get_card: "statuses/{}/card" => Card);
|
||||||
(get) get_card: "statuses/{}/card" => Card,
|
route_v1_id!((post) reblog: "statuses/{}/reblog" => Status);
|
||||||
(post) reblog: "statuses/{}/reblog" => Status,
|
route_v1_id!((post) unreblog: "statuses/{}/unreblog" => Status);
|
||||||
(post) unreblog: "statuses/{}/unreblog" => Status,
|
route_v1_id!((post) favourite: "statuses/{}/favourite" => Status);
|
||||||
(post) favourite: "statuses/{}/favourite" => Status,
|
route_v1_id!((post) unfavourite: "statuses/{}/unfavourite" => Status);
|
||||||
(post) unfavourite: "statuses/{}/unfavourite" => Status,
|
route_v1_id!((delete) delete_status: "statuses/{}" => Empty);
|
||||||
(delete) delete_status: "statuses/{}" => Empty,
|
route_v1_id!((get) get_filter: "filters/{}" => Filter);
|
||||||
(get) get_filter: "filters/{}" => Filter,
|
route_v1_id!((delete) delete_filter: "filters/{}" => Empty);
|
||||||
(delete) delete_filter: "filters/{}" => Empty,
|
route_v1_id!((delete) delete_from_suggestions: "suggestions/{}" => Empty);
|
||||||
(delete) delete_from_suggestions: "suggestions/{}" => Empty,
|
route_v1_id!((post) endorse_user: "accounts/{}/pin" => Relationship);
|
||||||
(post) endorse_user: "accounts/{}/pin" => Relationship,
|
route_v1_id!((post) unendorse_user: "accounts/{}/unpin" => Relationship);
|
||||||
(post) unendorse_user: "accounts/{}/unpin" => Relationship,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_filter(&self, request: &mut AddFilterRequest) -> Result<Filter> {
|
/// POST /api/v1/filters
|
||||||
|
pub fn add_filter(&self, request: &mut AddFilterRequest) -> Result<Filter> {
|
||||||
let url = self.route("/api/v1/filters");
|
let url = self.route("/api/v1/filters");
|
||||||
let response = self.send(self.client.post(&url).json(&request))?;
|
let response = self.send(self.client.post(&url).json(&request))?;
|
||||||
|
|
||||||
@@ -242,7 +240,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// PUT /api/v1/filters/:id
|
/// PUT /api/v1/filters/:id
|
||||||
fn update_filter(&self, id: &str, request: &mut AddFilterRequest) -> Result<Filter> {
|
pub fn update_filter(&self, id: &str, request: &mut AddFilterRequest) -> Result<Filter> {
|
||||||
let url = self.route(&format!("/api/v1/filters/{}", id));
|
let url = self.route(&format!("/api/v1/filters/{}", id));
|
||||||
let response = self.send(self.client.put(&url).json(&request))?;
|
let response = self.send(self.client.put(&url).json(&request))?;
|
||||||
|
|
||||||
@@ -257,7 +255,8 @@ impl MastodonClient for Mastodon {
|
|||||||
deserialise(response)
|
deserialise(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_credentials(&self, builder: &mut UpdateCredsRequest) -> Result<Account> {
|
/// PATCH /api/v1/accounts/update_credentials
|
||||||
|
pub fn update_credentials(&self, builder: &mut UpdateCredsRequest) -> Result<Account> {
|
||||||
let changes = builder.build()?;
|
let changes = builder.build()?;
|
||||||
let url = self.route("/api/v1/accounts/update_credentials");
|
let url = self.route("/api/v1/accounts/update_credentials");
|
||||||
let response = self.send(self.client.patch(&url).json(&changes))?;
|
let response = self.send(self.client.patch(&url).json(&changes))?;
|
||||||
@@ -274,7 +273,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Post a new status to the account.
|
/// Post a new status to the account.
|
||||||
fn new_status(&self, status: NewStatus) -> Result<Status> {
|
pub fn new_status(&self, status: NewStatus) -> Result<Status> {
|
||||||
let response = self.send(self.client.post(&self.route("/api/v1/statuses")).json(&status))?;
|
let response = self.send(self.client.post(&self.route("/api/v1/statuses")).json(&status))?;
|
||||||
|
|
||||||
deserialise(response)
|
deserialise(response)
|
||||||
@@ -282,7 +281,7 @@ impl MastodonClient for Mastodon {
|
|||||||
|
|
||||||
/// Get timeline filtered by a hashtag(eg. `#coffee`) either locally or
|
/// Get timeline filtered by a hashtag(eg. `#coffee`) either locally or
|
||||||
/// federated.
|
/// federated.
|
||||||
fn get_hashtag_timeline(&self, hashtag: &str, local: bool) -> Result<Page<Status>> {
|
pub fn get_hashtag_timeline(&self, hashtag: &str, local: bool) -> Result<Page<Status>> {
|
||||||
let base = "/api/v1/timelines/tag/";
|
let base = "/api/v1/timelines/tag/";
|
||||||
let url = if local {
|
let url = if local {
|
||||||
self.route(&format!("{}{}?local=1", base, hashtag))
|
self.route(&format!("{}{}?local=1", base, hashtag))
|
||||||
@@ -295,47 +294,7 @@ impl MastodonClient for Mastodon {
|
|||||||
|
|
||||||
/// Get statuses of a single account by id. Optionally only with pictures
|
/// Get statuses of a single account by id. Optionally only with pictures
|
||||||
/// and or excluding replies.
|
/// and or excluding replies.
|
||||||
///
|
pub fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status>>
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// # extern crate elefren;
|
|
||||||
/// # use elefren::prelude::*;
|
|
||||||
/// # use std::error::Error;
|
|
||||||
/// # fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
/// # let data = Data {
|
|
||||||
/// # base: "".into(),
|
|
||||||
/// # client_id: "".into(),
|
|
||||||
/// # client_secret: "".into(),
|
|
||||||
/// # redirect: "".into(),
|
|
||||||
/// # token: "".into(),
|
|
||||||
/// # };
|
|
||||||
/// let client = Mastodon::from(data);
|
|
||||||
/// let statuses = client.statuses("user-id", None)?;
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// # extern crate elefren;
|
|
||||||
/// # use elefren::prelude::*;
|
|
||||||
/// # use std::error::Error;
|
|
||||||
/// # fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
/// # let data = Data {
|
|
||||||
/// # base: "".into(),
|
|
||||||
/// # client_id: "".into(),
|
|
||||||
/// # client_secret: "".into(),
|
|
||||||
/// # redirect: "".into(),
|
|
||||||
/// # token: "".into(),
|
|
||||||
/// # };
|
|
||||||
/// let client = Mastodon::from(data);
|
|
||||||
/// let mut request = StatusesRequest::new();
|
|
||||||
/// request.only_media();
|
|
||||||
/// let statuses = client.statuses("user-id", request)?;
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status>>
|
|
||||||
where
|
where
|
||||||
S: Into<Option<StatusesRequest<'a>>>,
|
S: Into<Option<StatusesRequest<'a>>>,
|
||||||
{
|
{
|
||||||
@@ -352,7 +311,7 @@ impl MastodonClient for Mastodon {
|
|||||||
|
|
||||||
/// Returns the client account's relationship to a list of other accounts.
|
/// Returns the client account's relationship to a list of other accounts.
|
||||||
/// Such as whether they follow them or vice versa.
|
/// Such as whether they follow them or vice versa.
|
||||||
fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> {
|
pub fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> {
|
||||||
let mut url = self.route("/api/v1/accounts/relationships?");
|
let mut url = self.route("/api/v1/accounts/relationships?");
|
||||||
|
|
||||||
if ids.len() == 1 {
|
if ids.len() == 1 {
|
||||||
@@ -373,7 +332,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a push notifications subscription
|
/// Add a push notifications subscription
|
||||||
fn add_push_subscription(&self, request: &AddPushRequest) -> Result<Subscription> {
|
pub fn add_push_subscription(&self, request: &AddPushRequest) -> Result<Subscription> {
|
||||||
let request = request.build()?;
|
let request = request.build()?;
|
||||||
let response = self.send(self.client.post(&self.route("/api/v1/push/subscription")).json(&request))?;
|
let response = self.send(self.client.post(&self.route("/api/v1/push/subscription")).json(&request))?;
|
||||||
|
|
||||||
@@ -382,7 +341,7 @@ impl MastodonClient for Mastodon {
|
|||||||
|
|
||||||
/// Update the `data` portion of the push subscription associated with this
|
/// Update the `data` portion of the push subscription associated with this
|
||||||
/// access token
|
/// access token
|
||||||
fn update_push_data(&self, request: &UpdatePushRequest) -> Result<Subscription> {
|
pub fn update_push_data(&self, request: &UpdatePushRequest) -> Result<Subscription> {
|
||||||
let request = request.build();
|
let request = request.build();
|
||||||
let response = self.send(self.client.put(&self.route("/api/v1/push/subscription")).json(&request))?;
|
let response = self.send(self.client.put(&self.route("/api/v1/push/subscription")).json(&request))?;
|
||||||
|
|
||||||
@@ -390,48 +349,20 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get all accounts that follow the authenticated user
|
/// Get all accounts that follow the authenticated user
|
||||||
fn follows_me(&self) -> Result<Page<Account>> {
|
pub fn follows_me(&self) -> Result<Page<Account>> {
|
||||||
let me = self.verify_credentials()?;
|
let me = self.verify_credentials()?;
|
||||||
self.followers(&me.id)
|
self.followers(&me.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all accounts that the authenticated user follows
|
/// Get all accounts that the authenticated user follows
|
||||||
fn followed_by_me(&self) -> Result<Page<Account>> {
|
pub fn followed_by_me(&self) -> Result<Page<Account>> {
|
||||||
let me = self.verify_credentials()?;
|
let me = self.verify_credentials()?;
|
||||||
self.following(&me.id)
|
self.following(&me.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns events that are relevant to the authorized user, i.e. home
|
/// returns events that are relevant to the authorized user, i.e. home
|
||||||
/// timeline & notifications
|
/// timeline & notifications
|
||||||
///
|
pub fn streaming_user(&self) -> Result<MastodonStream> {
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// # extern crate elefren;
|
|
||||||
/// # use elefren::prelude::*;
|
|
||||||
/// # use std::error::Error;
|
|
||||||
/// use elefren::entities::event::Event;
|
|
||||||
/// # fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
/// # let data = Data {
|
|
||||||
/// # base: "".into(),
|
|
||||||
/// # client_id: "".into(),
|
|
||||||
/// # client_secret: "".into(),
|
|
||||||
/// # redirect: "".into(),
|
|
||||||
/// # token: "".into(),
|
|
||||||
/// # };
|
|
||||||
/// let client = Mastodon::from(data);
|
|
||||||
/// for event in client.streaming_user()? {
|
|
||||||
/// match event {
|
|
||||||
/// Event::Update(ref status) => { /* .. */ },
|
|
||||||
/// Event::Notification(ref notification) => { /* .. */ },
|
|
||||||
/// Event::Delete(ref id) => { /* .. */ },
|
|
||||||
/// Event::FiltersChanged => { /* .. */ },
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
fn streaming_user(&self) -> Result<Self::Stream> {
|
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -451,7 +382,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// returns all public statuses
|
/// returns all public statuses
|
||||||
fn streaming_public(&self) -> Result<Self::Stream> {
|
pub fn streaming_public(&self) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -471,7 +402,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all local statuses
|
/// Returns all local statuses
|
||||||
fn streaming_local(&self) -> Result<Self::Stream> {
|
pub fn streaming_local(&self) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -491,7 +422,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all public statuses for a particular hashtag
|
/// Returns all public statuses for a particular hashtag
|
||||||
fn streaming_public_hashtag(&self, hashtag: &str) -> Result<Self::Stream> {
|
pub fn streaming_public_hashtag(&self, hashtag: &str) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -512,7 +443,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all local statuses for a particular hashtag
|
/// Returns all local statuses for a particular hashtag
|
||||||
fn streaming_local_hashtag(&self, hashtag: &str) -> Result<Self::Stream> {
|
pub fn streaming_local_hashtag(&self, hashtag: &str) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -533,7 +464,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns statuses for a list
|
/// Returns statuses for a list
|
||||||
fn streaming_list(&self, list_id: &str) -> Result<Self::Stream> {
|
pub fn streaming_list(&self, list_id: &str) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -554,7 +485,7 @@ impl MastodonClient for Mastodon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all direct messages
|
/// Returns all direct messages
|
||||||
fn streaming_direct(&self) -> Result<Self::Stream> {
|
pub fn streaming_direct(&self) -> Result<MastodonStream> {
|
||||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("access_token", &self.token)
|
.append_pair("access_token", &self.token)
|
||||||
@@ -613,7 +544,7 @@ impl MastodonClient for Mastodon {
|
|||||||
/// ## Errors
|
/// ## Errors
|
||||||
/// This function may return an `Error::Http` before sending anything over the network if the
|
/// This function may return an `Error::Http` before sending anything over the network if the
|
||||||
/// `MediaBuilder` was supplied with a reader and a `mimetype` string which cannot be pasrsed.
|
/// `MediaBuilder` was supplied with a reader and a `mimetype` string which cannot be pasrsed.
|
||||||
fn media(&self, media: MediaBuilder) -> Result<Attachment> {
|
pub fn media(&self, media: MediaBuilder) -> Result<Attachment> {
|
||||||
use media_builder::MediaBuilderData;
|
use media_builder::MediaBuilderData;
|
||||||
|
|
||||||
let mut form = multipart::Form::new();
|
let mut form = multipart::Form::new();
|
||||||
@@ -676,6 +607,7 @@ impl EventStream for WebSocket {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Iterator that produces events from a mastodon streaming API event stream
|
/// Iterator that produces events from a mastodon streaming API event stream
|
||||||
pub struct EventReader<R: EventStream>(R);
|
pub struct EventReader<R: EventStream>(R);
|
||||||
|
|
||||||
impl<R: EventStream> Iterator for EventReader<R> {
|
impl<R: EventStream> Iterator for EventReader<R> {
|
||||||
type Item = Event;
|
type Item = Event;
|
||||||
|
|
||||||
@@ -683,15 +615,19 @@ impl<R: EventStream> Iterator for EventReader<R> {
|
|||||||
let mut lines = Vec::new();
|
let mut lines = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
if let Ok(line) = self.0.read_message() {
|
if let Ok(line) = self.0.read_message() {
|
||||||
|
debug!("WS rx: {}", line);
|
||||||
let line = line.trim().to_string();
|
let line = line.trim().to_string();
|
||||||
if line.starts_with(':') || line.is_empty() {
|
if line.starts_with(':') || line.is_empty() {
|
||||||
|
debug!("discard as comment");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
if let Ok(event) = self.make_event(&lines) {
|
if let Ok(event) = self.make_event(&lines) {
|
||||||
|
debug!("Parsed event");
|
||||||
lines.clear();
|
lines.clear();
|
||||||
return Some(event);
|
return Some(event);
|
||||||
} else {
|
} else {
|
||||||
|
debug!("Failed to parse");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -704,12 +640,14 @@ impl<R: EventStream> EventReader<R> {
|
|||||||
let event;
|
let event;
|
||||||
let data;
|
let data;
|
||||||
if let Some(event_line) = lines.iter().find(|line| line.starts_with("event:")) {
|
if let Some(event_line) = lines.iter().find(|line| line.starts_with("event:")) {
|
||||||
|
debug!("plaintext formatted event");
|
||||||
event = event_line[6..].trim().to_string();
|
event = event_line[6..].trim().to_string();
|
||||||
data = lines
|
data = lines
|
||||||
.iter()
|
.iter()
|
||||||
.find(|line| line.starts_with("data:"))
|
.find(|line| line.starts_with("data:"))
|
||||||
.map(|x| x[5..].trim().to_string());
|
.map(|x| x[5..].trim().to_string());
|
||||||
} else {
|
} else {
|
||||||
|
debug!("JSON formatted event");
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Message {
|
struct Message {
|
||||||
@@ -834,11 +772,9 @@ impl MastodonUnauth {
|
|||||||
|
|
||||||
Ok(EventReader(WebSocket(client)))
|
Ok(EventReader(WebSocket(client)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl MastodonUnauthenticated for MastodonUnauth {
|
|
||||||
/// GET /api/v1/statuses/:id
|
/// GET /api/v1/statuses/:id
|
||||||
fn get_status(&self, id: &str) -> Result<Status> {
|
pub fn get_status(&self, id: &str) -> Result<Status> {
|
||||||
let route = self.route("/api/v1/statuses")?;
|
let route = self.route("/api/v1/statuses")?;
|
||||||
let route = route.join(id)?;
|
let route = route.join(id)?;
|
||||||
let response = self.send(self.client.get(route))?;
|
let response = self.send(self.client.get(route))?;
|
||||||
@@ -846,7 +782,7 @@ impl MastodonUnauthenticated for MastodonUnauth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// GET /api/v1/statuses/:id/context
|
/// GET /api/v1/statuses/:id/context
|
||||||
fn get_context(&self, id: &str) -> Result<Context> {
|
pub fn get_context(&self, id: &str) -> Result<Context> {
|
||||||
let route = self.route("/api/v1/statuses")?;
|
let route = self.route("/api/v1/statuses")?;
|
||||||
let route = route.join(id)?;
|
let route = route.join(id)?;
|
||||||
let route = route.join("context")?;
|
let route = route.join("context")?;
|
||||||
@@ -855,7 +791,7 @@ impl MastodonUnauthenticated for MastodonUnauth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// GET /api/v1/statuses/:id/card
|
/// GET /api/v1/statuses/:id/card
|
||||||
fn get_card(&self, id: &str) -> Result<Card> {
|
pub fn get_card(&self, id: &str) -> Result<Card> {
|
||||||
let route = self.route("/api/v1/statuses")?;
|
let route = self.route("/api/v1/statuses")?;
|
||||||
let route = route.join(id)?;
|
let route = route.join(id)?;
|
||||||
let route = route.join("card")?;
|
let route = route.join("card")?;
|
||||||
|
|||||||
+44
-142
@@ -14,33 +14,15 @@ macro_rules! methods {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! paged_routes {
|
macro_rules! route_v1_paged {
|
||||||
|
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
|
||||||
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `", stringify!($method), " /api/v1/",
|
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set.",
|
"If `access_token` is not set.",
|
||||||
"\n",
|
|
||||||
"```no_run",
|
|
||||||
"# extern crate elefren;\n",
|
|
||||||
"# use elefren::prelude::*;\n",
|
|
||||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
|
||||||
"# let data = Data {\n",
|
|
||||||
"# base: \"https://example.com\".into(),\n",
|
|
||||||
"# client_id: \"taosuah\".into(),\n",
|
|
||||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
|
||||||
"# redirect: \"https://example.com\".into(),\n",
|
|
||||||
"# token: \"tsaohueaheis\".into(),\n",
|
|
||||||
"# };\n",
|
|
||||||
"let client = Mastodon::from(data);\n",
|
|
||||||
"client.", stringify!($name), "();\n",
|
|
||||||
"# Ok(())\n",
|
|
||||||
"# }\n",
|
|
||||||
"```"
|
|
||||||
),
|
),
|
||||||
fn $name(&self) -> Result<Page<$ret>> {
|
pub fn $name(&self) -> Result<Page<$ret>> {
|
||||||
let url = self.route(concat!("/api/v1/", $url));
|
let url = self.route(concat!("/api/v1/", $url));
|
||||||
let response = self.send(
|
let response = self.send(
|
||||||
self.client.$method(&url)
|
self.client.$method(&url)
|
||||||
@@ -48,20 +30,17 @@ macro_rules! paged_routes {
|
|||||||
|
|
||||||
Page::new(self, response)
|
Page::new(self, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paged_routes!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
((get ($($(#[$m:meta])* $param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
((get ($($(#[$m:meta])* $param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `get /api/v1/",
|
"Equivalent to `get /api/v1/", $url, "` with query params\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set."
|
"If `access_token` is not set.",
|
||||||
),
|
),
|
||||||
fn $name<'a>(&self, $($param: $typ,)*) -> Result<Page<$ret>> {
|
pub fn $name<'a>(&self, $($param: $typ,)*) -> Result<Page<$ret>> {
|
||||||
use serde_urlencoded;
|
use serde_urlencoded;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -95,22 +74,18 @@ macro_rules! paged_routes {
|
|||||||
Page::new(self, response)
|
Page::new(self, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paged_routes!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
() => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! route_v2 {
|
macro_rules! route_v2 {
|
||||||
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `get /api/v2/",
|
"Equivalent to `get /api/v2/",$url,"`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set."
|
"If `access_token` is not set."
|
||||||
),
|
),
|
||||||
fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
pub fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
||||||
use serde_urlencoded;
|
use serde_urlencoded;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -137,23 +112,18 @@ macro_rules! route_v2 {
|
|||||||
self.get(self.route(&url))
|
self.get(self.route(&url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
route_v2!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
() => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! route {
|
macro_rules! route_v1 {
|
||||||
|
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
|
||||||
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `get /api/v1/",
|
"Equivalent to `get /api/v1/", $url, "`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set."
|
"If `access_token` is not set."
|
||||||
),
|
),
|
||||||
fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
pub fn $name<'a>(&self, $($param: $typ,)*) -> Result<$ret> {
|
||||||
use serde_urlencoded;
|
use serde_urlencoded;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -180,18 +150,16 @@ macro_rules! route {
|
|||||||
self.get(self.route(&url))
|
self.get(self.route(&url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
route!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(($method:ident ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
(($method:ident ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty) => {
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `", stringify!($method), " /api/v1/",
|
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set.",
|
"If `access_token` is not set."
|
||||||
),
|
),
|
||||||
fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
pub fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
||||||
|
|
||||||
let form_data = serde_json::json!({
|
let form_data = serde_json::json!({
|
||||||
$(
|
$(
|
||||||
@@ -215,107 +183,45 @@ macro_rules! route {
|
|||||||
deserialise(response)
|
deserialise(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
route!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `", stringify!($method), " /api/v1/",
|
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set.",
|
"If `access_token` is not set."
|
||||||
"\n",
|
|
||||||
"```no_run",
|
|
||||||
"# extern crate elefren;\n",
|
|
||||||
"# use elefren::prelude::*;\n",
|
|
||||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
|
||||||
"# let data = Data {\n",
|
|
||||||
"# base: \"https://example.com\".into(),\n",
|
|
||||||
"# client_id: \"taosuah\".into(),\n",
|
|
||||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
|
||||||
"# redirect: \"https://example.com\".into(),\n",
|
|
||||||
"# token: \"tsaohueaheis\".into(),\n",
|
|
||||||
"# };\n",
|
|
||||||
"let client = Mastodon::from(data);\n",
|
|
||||||
"client.", stringify!($name), "();\n",
|
|
||||||
"# Ok(())\n",
|
|
||||||
"# }\n",
|
|
||||||
"```"
|
|
||||||
),
|
),
|
||||||
fn $name(&self) -> Result<$ret> {
|
pub fn $name(&self) -> Result<$ret> {
|
||||||
self.$method(self.route(concat!("/api/v1/", $url)))
|
self.$method(self.route(concat!("/api/v1/", $url)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
route!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
() => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! route_id {
|
macro_rules! route_v1_id {
|
||||||
|
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
|
||||||
($(($method:ident) $name:ident: $url:expr => $ret:ty,)*) => {
|
|
||||||
$(
|
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `", stringify!($method), " /api/v1/",
|
"Equivalent to `", stringify!($method), " /api/v1/", $url, "`\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set.",
|
"If `access_token` is not set."
|
||||||
"\n",
|
|
||||||
"```no_run",
|
|
||||||
"# extern crate elefren;\n",
|
|
||||||
"# use elefren::prelude::*;\n",
|
|
||||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
|
||||||
"# let data = Data {\n",
|
|
||||||
"# base: \"https://example.com\".into(),\n",
|
|
||||||
"# client_id: \"taosuah\".into(),\n",
|
|
||||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
|
||||||
"# redirect: \"https://example.com\".into(),\n",
|
|
||||||
"# token: \"tsaohueaheis\".into(),\n",
|
|
||||||
"# };\n",
|
|
||||||
"let client = Mastodon::from(data);\n",
|
|
||||||
"client.", stringify!($name), "(\"42\");\n",
|
|
||||||
"# Ok(())\n",
|
|
||||||
"# }\n",
|
|
||||||
"```"
|
|
||||||
),
|
),
|
||||||
fn $name(&self, id: &str) -> Result<$ret> {
|
pub fn $name(&self, id: &str) -> Result<$ret> {
|
||||||
self.$method(self.route(&format!(concat!("/api/v1/", $url), id)))
|
self.$method(self.route(&format!(concat!("/api/v1/", $url), id)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
macro_rules! paged_routes_with_id {
|
macro_rules! route_v1_paged_id {
|
||||||
|
(($method:ident) $name:ident: $url:expr => $ret:ty) => {
|
||||||
(($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
||||||
doc_comment::doc_comment! {
|
doc_comment::doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
"Equivalent to `", stringify!($method), " /api/v1/",
|
"Equivalent to `", stringify!($method), " /api/v1/", $url, "` with ID\n",
|
||||||
$url,
|
"# Errors\n",
|
||||||
"`\n# Errors\nIf `access_token` is not set.",
|
"If `access_token` is not set."
|
||||||
"\n",
|
|
||||||
"```no_run",
|
|
||||||
"# extern crate elefren;\n",
|
|
||||||
"# use elefren::prelude::*;\n",
|
|
||||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
|
||||||
"# let data = Data {\n",
|
|
||||||
"# base: \"https://example.com\".into(),\n",
|
|
||||||
"# client_id: \"taosuah\".into(),\n",
|
|
||||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
|
||||||
"# redirect: \"https://example.com\".into(),\n",
|
|
||||||
"# token: \"tsaohueaheis\".into(),\n",
|
|
||||||
"# };\n",
|
|
||||||
"let client = Mastodon::from(data);\n",
|
|
||||||
"client.", stringify!($name), "(\"some-id\");\n",
|
|
||||||
"# Ok(())\n",
|
|
||||||
"# }\n",
|
|
||||||
"```"
|
|
||||||
),
|
),
|
||||||
fn $name(&self, id: &str) -> Result<Page<$ret>> {
|
pub fn $name(&self, id: &str) -> Result<Page<$ret>> {
|
||||||
let url = self.route(&format!(concat!("/api/v1/", $url), id));
|
let url = self.route(&format!(concat!("/api/v1/", $url), id));
|
||||||
let response = self.send(
|
let response = self.send(
|
||||||
self.client.$method(&url)
|
self.client.$method(&url)
|
||||||
@@ -324,9 +230,5 @@ macro_rules! paged_routes_with_id {
|
|||||||
Page::new(self, response)
|
Page::new(self, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paged_routes_with_id!{$($rest)*}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
() => {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user