Merge pull request #3 from pwoolcoc/mastodon-client-trait

Adds a `MastodonClient` trait
This commit is contained in:
Paul Woolcock
2018-08-21 16:38:34 -04:00
committed by GitHub
8 changed files with 87 additions and 26 deletions
+1
View File
@@ -1,5 +1,6 @@
mod register;
use register::MastodonClient;
use std::error;
fn main() -> Result<(), Box<error::Error>> {
+2
View File
@@ -1,7 +1,9 @@
mod register;
use register::MastodonClient;
use std::error;
fn main() -> Result<(), Box<error::Error>> {
let mastodon = register::get_mastodon_data()?;
let you = mastodon.verify_credentials()?;
+2
View File
@@ -1,6 +1,8 @@
extern crate mammut;
extern crate toml;
pub use self::mammut::MastodonClient;
use std::{
error::Error,
fs,
+1
View File
@@ -1,5 +1,6 @@
mod register;
use register::MastodonClient;
use std::error;
fn main() -> Result<(), Box<error::Error>> {
+1
View File
@@ -1,5 +1,6 @@
mod register;
use register::MastodonClient;
use std::error;
fn main() -> Result<(), Box<error::Error>> {
+1 -1
View File
@@ -5,7 +5,7 @@ use serde::Deserialize;
///
/// ```no_run
/// # extern crate mammut;
/// # use mammut::{Data, Mastodon};
/// # use mammut::{Data, Mastodon, MastodonClient};
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<Error>> {
/// # let data = Data {
+78 -24
View File
@@ -9,7 +9,7 @@
//! # try().unwrap();
//! # }
//! # fn try() -> mammut::Result<()> {
//! use mammut::Registration;
//! use mammut::{MastodonClient, Registration};
//! use mammut::apps::{AppBuilder, Scopes};
//!
//! let app = AppBuilder {
@@ -98,7 +98,7 @@ macro_rules! paged_routes {
"Equivalent to `/api/v1/",
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self) -> Result<Page<$ret>> {
fn $name(&self) -> Result<Page<$ret>> {
let url = self.route(concat!("/api/v1/", $url));
let response = self.client.$method(&url)
.headers(self.headers.clone())
@@ -123,7 +123,7 @@ macro_rules! route {
"Equivalent to `/api/v1/",
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
use reqwest::multipart::Form;
let form_data = Form::new()
@@ -158,7 +158,7 @@ macro_rules! route {
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
let form_data = json!({
$(
@@ -192,7 +192,7 @@ macro_rules! route {
"Equivalent to `/api/v1/",
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self) -> Result<$ret> {
fn $name(&self) -> Result<$ret> {
self.$method(self.route(concat!("/api/v1/", $url)))
}
}
@@ -212,7 +212,7 @@ macro_rules! route_id {
"Equivalent to `/api/v1/",
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self, id: u64) -> Result<$ret> {
fn $name(&self, id: u64) -> Result<$ret> {
self.$method(self.route(&format!(concat!("/api/v1/", $url), id)))
}
}
@@ -228,7 +228,7 @@ macro_rules! paged_routes_with_id {
"Equivalent to `/api/v1/",
$url,
"`\n# Errors\nIf `access_token` is not set."),
pub fn $name(&self, id: &str) -> Result<Page<$ret>> {
fn $name(&self, id: &str) -> Result<Page<$ret>> {
let url = self.route(&format!(concat!("/api/v1/", $url), id));
let response = self.client.$method(&url)
.headers(self.headers.clone())
@@ -433,6 +433,57 @@ impl<'a> StatusesRequest<'a> {
}
}
#[allow(unused)]
pub trait MastodonClient {
fn favourites(&self) -> Result<Page<Status>> { unimplemented!("This method was not implemented"); }
fn blocks(&self) -> Result<Page<Account>> { unimplemented!("This method was not implemented"); }
fn domain_blocks(&self) -> Result<Page<String>> { unimplemented!("This method was not implemented"); }
fn follow_requests(&self) -> Result<Page<Account>> { unimplemented!("This method was not implemented"); }
fn get_home_timeline(&self) -> Result<Page<Status>> { unimplemented!("This method was not implemented"); }
fn get_emojis(&self) -> Result<Page<Emoji>> { unimplemented!("This method was not implemented"); }
fn mutes(&self) -> Result<Page<Account>> { unimplemented!("This method was not implemented"); }
fn notifications(&self) -> Result<Page<Notification>> { unimplemented!("This method was not implemented"); }
fn reports(&self) -> Result<Page<Report>> { unimplemented!("This method was not implemented"); }
fn followers(&self, id: &str) -> Result<Page<Account>> { unimplemented!("This method was not implemented"); }
fn following(&self) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn reblogged_by(&self) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn favourited_by(&self) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn unblock_domain(&self, domain: String) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn instance(&self) -> Result<Instance> { unimplemented!("This method was not implemented"); }
fn verify_credentials(&self) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn report(&self, account_id: &str, status_ids: Vec<&str>, comment: String) -> Result<Report> { unimplemented!("This method was not implemented"); }
fn block_domain(&self, domain: String) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn authorize_follow_request(&self, id: &str) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn reject_follow_request(&self, id: &str) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn search(&self, q: String, resolve: bool) -> Result<SearchResult> { unimplemented!("This method was not implemented"); }
fn follows(&self, uri: Cow<'static, str>) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn media(&self, file: Cow<'static, str>) -> Result<Attachment> { unimplemented!("This method was not implemented"); }
fn clear_notifications(&self) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn get_account(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn follow(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn unfollow(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn block(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn unblock(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn mute(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn unmute(&self, id: u64) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn get_notification(&self, id: u64) -> Result<Notification> { unimplemented!("This method was not implemented"); }
fn get_status(&self, id: u64) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn get_context(&self, id: u64) -> Result<Context> { unimplemented!("This method was not implemented"); }
fn get_card(&self, id: u64) -> Result<Card> { unimplemented!("This method was not implemented"); }
fn reblog(&self, id: u64) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn unreblog(&self, id: u64) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn favourite(&self, id: u64) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn unfavourite(&self, id: u64) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn delete_status(&self, id: u64) -> Result<Empty> { unimplemented!("This method was not implemented"); }
fn update_credentials(&self, changes: CredientialsBuilder) -> Result<Account> { unimplemented!("This method was not implemented"); }
fn new_status(&self, status: StatusBuilder) -> Result<Status> { unimplemented!("This method was not implemented"); }
fn get_public_timeline(&self, local: bool) -> Result<Vec<Status>> { unimplemented!("This method was not implemented"); }
fn get_tagged_timeline(&self, hashtag: String, local: bool) -> Result<Vec<Status>> { unimplemented!("This method was not implemented"); }
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status>> where S: Into<Option<StatusesRequest<'a>>> { unimplemented!("This method was not implemented"); }
fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> { unimplemented!("This method was not implemented"); }
fn search_accounts(&self, query: &str, limit: Option<u64>, following: bool) -> Result<Page<Account>> { unimplemented!("This method was not implemented"); }
}
impl Mastodon {
fn from_registration<I>(base: I,
client_id: I,
@@ -474,6 +525,17 @@ impl Mastodon {
}
}
methods![get, post, delete,];
fn route(&self, url: &str) -> String {
let mut s = (*self.base).to_owned();
s += url;
s
}
}
impl MastodonClient for Mastodon {
paged_routes! {
(get) favourites: "favourites" => Status,
(get) blocks: "blocks" => Account,
@@ -526,7 +588,7 @@ impl Mastodon {
(delete) delete_status: "statuses/{}" => Empty,
}
pub fn update_credentials(&self, changes: CredientialsBuilder)
fn update_credentials(&self, changes: CredientialsBuilder)
-> Result<Account>
{
@@ -548,7 +610,7 @@ impl Mastodon {
}
/// Post a new status to the account.
pub fn new_status(&self, status: StatusBuilder) -> Result<Status> {
fn new_status(&self, status: StatusBuilder) -> Result<Status> {
let response = self.client.post(&self.route("/api/v1/statuses"))
.headers(self.headers.clone())
@@ -559,7 +621,7 @@ impl Mastodon {
}
/// Get the federated timeline for the instance.
pub fn get_public_timeline(&self, local: bool) -> Result<Vec<Status>> {
fn get_public_timeline(&self, local: bool) -> Result<Vec<Status>> {
let mut url = self.route("/api/v1/timelines/public");
if local {
@@ -571,7 +633,7 @@ impl Mastodon {
/// Get timeline filtered by a hashtag(eg. `#coffee`) either locally or
/// federated.
pub fn get_tagged_timeline(&self, hashtag: String, local: bool) -> Result<Vec<Status>> {
fn get_tagged_timeline(&self, hashtag: String, local: bool) -> Result<Vec<Status>> {
let mut url = self.route("/api/v1/timelines/tag/");
url += &hashtag;
@@ -589,7 +651,7 @@ impl Mastodon {
///
/// ```no_run
/// # extern crate mammut;
/// # use mammut::{Data, Mastodon};
/// # use mammut::{Data, Mastodon, MastodonClient};
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<Error>> {
/// # let data = Data {
@@ -607,7 +669,7 @@ impl Mastodon {
///
/// ```no_run
/// # extern crate mammut;
/// # use mammut::{Data, Mastodon, StatusesRequest};
/// # use mammut::{Data, Mastodon, MastodonClient, StatusesRequest};
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<Error>> {
/// # let data = Data {
@@ -624,7 +686,7 @@ impl Mastodon {
/// # Ok(())
/// # }
/// ```
pub fn statuses<'a, S>(&self, id: &str, request: S) -> Result<Page<Status>>
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status>>
where S: Into<Option<StatusesRequest<'a>>>
{
let mut url = format!("{}/api/v1/accounts/{}/statuses", self.base, id);
@@ -642,7 +704,7 @@ impl Mastodon {
/// Returns the client account's relationship to a list of other accounts.
/// Such as whether they follow them or vice versa.
pub fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> {
fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> {
let mut url = self.route("/api/v1/accounts/relationships?");
if ids.len() == 1 {
@@ -667,7 +729,7 @@ impl Mastodon {
/// Search for accounts by their name.
/// Will lookup an account remotely if the search term is in the
/// `username@domain` format and not yet in the database.
pub fn search_accounts(&self,
fn search_accounts(&self,
query: &str,
limit: Option<u64>,
following: bool)
@@ -685,14 +747,6 @@ impl Mastodon {
Page::new(self, response)
}
methods![get, post, delete,];
fn route(&self, url: &str) -> String {
let mut s = (*self.base).to_owned();
s += url;
s
}
}
impl ops::Deref for Mastodon {
+1 -1
View File
@@ -52,7 +52,7 @@ impl Registration {
/// # try().unwrap();
/// # }
/// # fn try() -> mammut::Result<()> {
/// use mammut::Registration;
/// use mammut::{MastodonClient, Registration};
/// use mammut::apps::{AppBuilder, Scopes};
///
/// let app = AppBuilder {