diff --git a/README.md b/README.md index 88bf58d..28d29a1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## [Documentation](https://docs.rs/elefren/) -A wrapper around the [API](https://github.com/tootsuite/mastodon/blob/master/docs/Using-the-API/API.md#tag) for [Mastodon](https://mastodon.social/) +A wrapper around the [API](https://github.com/tootsuite/documentation/blob/master/docs/Using-the-API/API.md#tag) for [Mastodon](https://mastodon.social/) ```rust extern crate elefren; diff --git a/examples/print_your_profile.rs b/examples/print_your_profile.rs index 515c7c4..47a15ec 100644 --- a/examples/print_your_profile.rs +++ b/examples/print_your_profile.rs @@ -3,7 +3,6 @@ mod register; use register::MastodonClient; use std::error; - fn main() -> Result<(), Box> { let mastodon = register::get_mastodon_data()?; let you = mastodon.verify_credentials()?; diff --git a/examples/register.rs b/examples/register.rs index f042291..c5479d8 100644 --- a/examples/register.rs +++ b/examples/register.rs @@ -3,19 +3,12 @@ extern crate toml; pub use self::elefren::{Data, MastodonClient}; -use std::{ - error::Error, - fs, - io, -}; +use std::{error::Error, fs, io}; use self::elefren::{ - apps::{ - App, - Scopes - }, + apps::{App, Scopes}, Mastodon, - Registration + Registration, }; #[allow(dead_code)] @@ -24,7 +17,6 @@ fn main() -> Result<(), Box> { Ok(()) } - #[allow(dead_code)] pub fn get_mastodon_data() -> Result> { if let Ok(config) = fs::read_to_string("mastodon-data.toml") { @@ -38,8 +30,8 @@ pub fn get_mastodon_data() -> Result> { pub fn register() -> Result> { let mut app = App::builder(); app.client_name("elefren-examples") - .scopes(Scopes::All) - .website("https://github.com/pwoolcoc/elefren"); + .scopes(Scopes::All) + .website("https://github.com/pwoolcoc/elefren"); let website = read_line("Please enter your mastodon instance url:")?; let registration = Registration::new(website.trim()); @@ -67,4 +59,3 @@ pub fn read_line(message: &str) -> Result> { Ok(input) } - diff --git a/rustfmt.toml b/rustfmt.toml index 1aabd5c..e2b5e5b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,3 @@ -indent_style = "Visual" format_strings = true format_macro_matchers = true imports_layout = "HorizontalVertical" diff --git a/src/apps.rs b/src/apps.rs index eb380b2..cc70bc0 100644 --- a/src/apps.rs +++ b/src/apps.rs @@ -1,5 +1,4 @@ -use std::fmt; -use std::borrow::Cow; +use std::{borrow::Cow, fmt}; use try_from::TryInto; @@ -8,13 +7,8 @@ use errors::{Error, Result}; /// Provides the necessary types for registering an App and getting the /// necessary auth information pub mod prelude { - pub use { - apps::{ - App, - Scopes - }, - registration::Registration - }; + pub use apps::{App, Scopes}; + pub use registration::Registration; } /// Represents an application that can be registered with a mastodon instance @@ -23,7 +17,7 @@ pub struct App { client_name: String, redirect_uris: String, scopes: Scopes, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] website: Option, } @@ -39,8 +33,8 @@ impl App { /// Builder struct for defining your application. /// ``` -/// use std::error::Error; /// use elefren::apps::prelude::*; +/// use std::error::Error; /// /// # fn main() -> Result<(), Box> { /// let mut builder = App::builder(); @@ -98,14 +92,15 @@ impl<'a> AppBuilder<'a> { /// Will fail if no `client_name` was provided pub fn build(self) -> Result { Ok(App { - client_name: self.client_name - .ok_or_else(|| Error::MissingField("client_name"))? - .into(), - redirect_uris: self.redirect_uris - .unwrap_or_else(|| "urn:ietf:wg:oauth:2.0:oob".into()) - .into(), - scopes: self.scopes - .unwrap_or_else(|| Scopes::Read), + client_name: self + .client_name + .ok_or_else(|| Error::MissingField("client_name"))? + .into(), + redirect_uris: self + .redirect_uris + .unwrap_or_else(|| "urn:ietf:wg:oauth:2.0:oob".into()) + .into(), + scopes: self.scopes.unwrap_or_else(|| Scopes::Read), website: self.website.map(|s| s.into()), }) } @@ -128,7 +123,8 @@ impl<'a> TryInto for AppBuilder<'a> { } /// Permission scope of the application. -/// [Details on what each permission provides](//github.com/tootsuite/documentation/blob/master/Using-the-API/OAuth-details.md) +/// [Details on what each permission provides][1] +/// [1]: https://github.com/tootsuite/documentation/blob/master/Using-the-API/OAuth-details.md) #[derive(Debug, Clone, Copy, Serialize)] pub enum Scopes { /// All Permissions, equivalent to `read write follow` @@ -157,15 +153,19 @@ pub enum Scopes { impl fmt::Display for Scopes { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::Scopes::*; - write!(f, "{}", match *self { - All => "read%20write%20follow", - Follow => "follow", - Read => "read", - ReadFollow => "read%20follow", - ReadWrite => "read%20write", - Write => "write", - WriteFollow => "write%20follow" - }) + write!( + f, + "{}", + match *self { + All => "read%20write%20follow", + Follow => "follow", + Read => "read", + ReadFollow => "read%20follow", + ReadWrite => "read%20write", + Write => "write", + WriteFollow => "write%20follow", + } + ) } } diff --git a/src/entities/account.rs b/src/entities/account.rs index eadd2a5..b244425 100644 --- a/src/entities/account.rs +++ b/src/entities/account.rs @@ -2,9 +2,9 @@ use chrono::prelude::*; use reqwest::multipart::Form; -use ::Result; -use std::path::Path; use serde::de::{self, Deserialize, Deserializer, Unexpected}; +use std::path::Path; +use Result; /// A struct representing an Account. #[derive(Debug, Clone, Deserialize)] @@ -57,9 +57,7 @@ pub struct Source { note: String, } -fn string_or_bool<'de, D: Deserializer<'de>>(val: D) - -> ::std::result::Result -{ +fn string_or_bool<'de, D: Deserializer<'de>>(val: D) -> ::std::result::Result { #[derive(Clone, Debug, Deserialize)] #[serde(untagged)] pub enum BoolOrString { @@ -68,16 +66,19 @@ fn string_or_bool<'de, D: Deserializer<'de>>(val: D) } Ok(match BoolOrString::deserialize(val)? { - BoolOrString::Bool(b) => b, - BoolOrString::Str(ref s) => { - if s == "true" { - true - } else if s == "false" { - false - } else { - return Err(de::Error::invalid_value(Unexpected::Str(s), &"true or false")); - } + BoolOrString::Bool(b) => b, + BoolOrString::Str(ref s) => { + if s == "true" { + true + } else if s == "false" { + false + } else { + return Err(de::Error::invalid_value( + Unexpected::Str(s), + &"true or false", + )); } + }, }) } diff --git a/src/entities/attachment.rs b/src/entities/attachment.rs index dbc560f..e1bfc47 100644 --- a/src/entities/attachment.rs +++ b/src/entities/attachment.rs @@ -6,7 +6,7 @@ pub struct Attachment { /// ID of the attachment. pub id: String, /// The media type of an attachment. - #[serde(rename="type")] + #[serde(rename = "type")] pub media_type: MediaType, /// URL of the locally hosted version of the image. pub url: String, @@ -43,7 +43,6 @@ pub struct ImageDetails { size: String, /// The aspect ratio of the attachment. aspect: f64, - } /// The type of media attachment. diff --git a/src/entities/itemsiter.rs b/src/entities/itemsiter.rs index 7e47c4f..6b7db1b 100644 --- a/src/entities/itemsiter.rs +++ b/src/entities/itemsiter.rs @@ -18,7 +18,7 @@ use serde::Deserialize; /// let client = Mastodon::from(data); /// let statuses = client.statuses("user-id", None)?; /// for status in statuses.items_iter() { -/// // do something with `status` +/// // do something with `status` /// } /// # Ok(()) /// # } @@ -33,7 +33,7 @@ pub(crate) struct ItemsIter<'a, T: Clone + for<'de> Deserialize<'de>> { impl<'a, T: Clone + for<'de> Deserialize<'de>> ItemsIter<'a, T> { pub(crate) fn new(page: Page<'a, T>) -> ItemsIter<'a, T> { ItemsIter { - page: page, + page, buffer: vec![], cur_idx: 0, use_initial: true, @@ -41,8 +41,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>> ItemsIter<'a, T> { } fn need_next_page(&self) -> bool { - self.buffer.is_empty() || - self.cur_idx == self.buffer.len() + self.buffer.is_empty() || self.cur_idx == self.buffer.len() } fn fill_next_page(&mut self) -> Option<()> { @@ -61,7 +60,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>> ItemsIter<'a, T> { } } -impl<'a, T: Clone+ for<'de> Deserialize<'de>> Iterator for ItemsIter<'a, T> { +impl<'a, T: Clone + for<'de> Deserialize<'de>> Iterator for ItemsIter<'a, T> { type Item = T; fn next(&mut self) -> Option { diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 9da56b3..6879e16 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -3,10 +3,10 @@ pub mod attachment; pub mod card; pub mod context; pub mod instance; +pub(crate) mod itemsiter; pub mod list; pub mod mention; pub mod notification; -pub(crate) mod itemsiter; pub mod relationship; pub mod report; pub mod search_result; @@ -17,19 +17,22 @@ pub mod status; pub struct Empty {} pub mod prelude { - //! The purpose of this module is to alleviate imports of many common structs - //! by adding a glob import to the top of mastodon heavy modules: - pub use super::Empty; - pub use super::account::{Account, CredientialsBuilder, Source}; - pub use super::attachment::{Attachment, MediaType}; - pub use super::card::Card; - pub use super::context::Context; - pub use super::instance::*; - pub use super::list::List; - pub use super::mention::Mention; - pub use super::notification::Notification; - pub use super::relationship::Relationship; - pub use super::report::Report; - pub use super::search_result::SearchResult; - pub use super::status::{Application, Emoji, Status}; + //! The purpose of this module is to alleviate imports of many common + //! structs by adding a glob import to the top of mastodon heavy + //! modules: + pub use super::{ + account::{Account, CredientialsBuilder, Source}, + attachment::{Attachment, MediaType}, + card::Card, + context::Context, + instance::*, + list::List, + mention::Mention, + notification::Notification, + relationship::Relationship, + report::Report, + search_result::SearchResult, + status::{Application, Emoji, Status}, + Empty, + }; } diff --git a/src/entities/notification.rs b/src/entities/notification.rs index 41074e3..1fbd919 100644 --- a/src/entities/notification.rs +++ b/src/entities/notification.rs @@ -1,8 +1,7 @@ //! Module containing all info about notifications. +use super::{account::Account, status::Status}; use chrono::prelude::*; -use super::account::Account; -use super::status::Status; /// A struct containing info about a notification. #[derive(Debug, Clone, Deserialize)] diff --git a/src/entities/status.rs b/src/entities/status.rs index 158ba0a..c2f9f6f 100644 --- a/src/entities/status.rs +++ b/src/entities/status.rs @@ -1,7 +1,7 @@ //! Module containing all info relating to a status. -use chrono::prelude::*; use super::prelude::*; +use chrono::prelude::*; use status_builder::Visibility; /// A status from the instance. diff --git a/src/errors.rs b/src/errors.rs index bae7fa3..4af0600 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,12 +1,7 @@ -use std::{ - fmt, - error, - io::Error as IoError -}; +use std::{error, fmt, io::Error as IoError}; use json::Error as SerdeError; -use reqwest::Error as HttpError; -use reqwest::StatusCode; +use reqwest::{Error as HttpError, StatusCode}; use url::ParseError as UrlError; /// Convience type over `std::result::Result` with `Error` as the error type. @@ -52,11 +47,12 @@ impl fmt::Display for Error { impl error::Error for Error { fn description(&self) -> &str { match *self { - Error::Api(ref e) => { - e.error_description.as_ref().map(|i| &**i) - .or(e.error.as_ref().map(|i| &**i)) - .unwrap_or("Unknown API Error") - }, + Error::Api(ref e) => e + .error_description + .as_ref() + .map(|i| &**i) + .or(e.error.as_ref().map(|i| &**i)) + .unwrap_or("Unknown API Error"), Error::Serde(ref e) => e.description(), Error::Http(ref e) => e.description(), Error::Io(ref e) => e.description(), diff --git a/src/lib.rs b/src/lib.rs index a60e89d..d05c372 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,14 +9,12 @@ //! # try().unwrap(); //! # } //! # fn try() -> elefren::Result<()> { -//! use elefren::prelude::*; -//! use elefren::apps::prelude::*; +//! use elefren::{apps::prelude::*, prelude::*}; //! //! let mut app = App::builder(); //! app.client_name("elefren_test"); //! -//! let registration = Registration::new("https://mastodon.social") -//! .register(app)?; +//! let registration = Registration::new("https://mastodon.social").register(app)?; //! let url = registration.authorize_url()?; //! // Here you now need to open the url in the browser //! // And handle a the redirect url coming back with the code. @@ -31,47 +29,57 @@ #![cfg_attr(test, deny(warnings))] #![cfg_attr(test, deny(missing_docs))] -#[macro_use] extern crate serde_derive; -#[macro_use] extern crate doc_comment; -#[macro_use] extern crate serde_json as json; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate doc_comment; +#[macro_use] +extern crate serde_json as json; extern crate chrono; extern crate reqwest; extern crate serde; extern crate try_from; extern crate url; -use std::borrow::Cow; -use std::ops; +use std::{borrow::Cow, ops}; -use reqwest::{Client, Response}; -use reqwest::header::{Authorization, Bearer, Headers}; +use reqwest::{ + header::{Authorization, Bearer, Headers}, + Client, + Response, +}; use entities::prelude::*; use page::Page; -pub use status_builder::StatusBuilder; -pub use requests::statuses::StatusesRequest; -pub use errors::{Result, Error, ApiError}; +pub use errors::{ApiError, Error, Result}; pub use registration::Registration; +pub use requests::statuses::StatusesRequest; +pub use status_builder::StatusBuilder; /// Registering your App pub mod apps; -/// Constructing a status -pub mod status_builder; /// Entities returned from the API pub mod entities; -/// Registering your app. -pub mod registration; -/// Handling multiple pages of entities. -pub mod page; /// Errors pub mod errors; +/// Handling multiple pages of entities. +pub mod page; +/// Registering your app. +pub mod registration; /// Requests pub mod requests; -#[macro_use] mod macros; +/// Constructing a status +pub mod status_builder; +#[macro_use] +mod macros; /// Automatically import the things you need pub mod prelude { - pub use {Data, Mastodon, MastodonClient, StatusBuilder, StatusesRequest}; + pub use Data; + pub use Mastodon; + pub use MastodonClient; + pub use StatusBuilder; + pub use StatusesRequest; } /// Your mastodon application client, handles all requests to and from Mastodon. @@ -80,7 +88,7 @@ pub struct Mastodon { client: Client, headers: Headers, /// Raw data about your mastodon instance. - pub data: Data + pub data: Data, } /// Raw data about mastodon app. Save `Data` using `serde` to prevent needing @@ -103,53 +111,155 @@ pub struct Data { /// implementations might be swapped out for testing #[allow(unused)] pub trait MastodonClient { - fn favourites(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn blocks(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn domain_blocks(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn follow_requests(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn get_home_timeline(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn get_emojis(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn mutes(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn notifications(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn reports(&self) -> Result> { unimplemented!("This method was not implemented"); } - fn followers(&self, id: &str) -> Result> { unimplemented!("This method was not implemented"); } - fn following(&self) -> Result { unimplemented!("This method was not implemented"); } - fn reblogged_by(&self) -> Result { unimplemented!("This method was not implemented"); } - fn favourited_by(&self) -> Result { unimplemented!("This method was not implemented"); } - fn unblock_domain(&self, domain: String) -> Result { unimplemented!("This method was not implemented"); } - fn instance(&self) -> Result { unimplemented!("This method was not implemented"); } - fn verify_credentials(&self) -> Result { unimplemented!("This method was not implemented"); } - fn report(&self, account_id: &str, status_ids: Vec<&str>, comment: String) -> Result { unimplemented!("This method was not implemented"); } - fn block_domain(&self, domain: String) -> Result { unimplemented!("This method was not implemented"); } - fn authorize_follow_request(&self, id: &str) -> Result { unimplemented!("This method was not implemented"); } - fn reject_follow_request(&self, id: &str) -> Result { unimplemented!("This method was not implemented"); } - fn search(&self, q: String, resolve: bool) -> Result { unimplemented!("This method was not implemented"); } - fn follows(&self, uri: Cow<'static, str>) -> Result { unimplemented!("This method was not implemented"); } - fn media(&self, file: Cow<'static, str>) -> Result { unimplemented!("This method was not implemented"); } - fn clear_notifications(&self) -> Result { unimplemented!("This method was not implemented"); } - fn get_account(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn follow(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn unfollow(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn block(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn unblock(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn mute(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn unmute(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn get_notification(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn get_status(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn get_context(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn get_card(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn reblog(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn unreblog(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn favourite(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn unfavourite(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn delete_status(&self, id: u64) -> Result { unimplemented!("This method was not implemented"); } - fn update_credentials(&self, changes: CredientialsBuilder) -> Result { unimplemented!("This method was not implemented"); } - fn new_status(&self, status: StatusBuilder) -> Result { unimplemented!("This method was not implemented"); } - fn get_public_timeline(&self, local: bool) -> Result> { unimplemented!("This method was not implemented"); } - fn get_tagged_timeline(&self, hashtag: String, local: bool) -> Result> { unimplemented!("This method was not implemented"); } - fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result> where S: Into>> { unimplemented!("This method was not implemented"); } - fn relationships(&self, ids: &[&str]) -> Result> { unimplemented!("This method was not implemented"); } - fn search_accounts(&self, query: &str, limit: Option, following: bool) -> Result> { unimplemented!("This method was not implemented"); } + fn favourites(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn blocks(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn domain_blocks(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn follow_requests(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn get_home_timeline(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn get_emojis(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn mutes(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn notifications(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn reports(&self) -> Result> { + unimplemented!("This method was not implemented"); + } + fn followers(&self, id: &str) -> Result> { + unimplemented!("This method was not implemented"); + } + fn following(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn reblogged_by(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn favourited_by(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn unblock_domain(&self, domain: String) -> Result { + unimplemented!("This method was not implemented"); + } + fn instance(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn verify_credentials(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn report(&self, account_id: &str, status_ids: Vec<&str>, comment: String) -> Result { + unimplemented!("This method was not implemented"); + } + fn block_domain(&self, domain: String) -> Result { + unimplemented!("This method was not implemented"); + } + fn authorize_follow_request(&self, id: &str) -> Result { + unimplemented!("This method was not implemented"); + } + fn reject_follow_request(&self, id: &str) -> Result { + unimplemented!("This method was not implemented"); + } + fn search(&self, q: String, resolve: bool) -> Result { + unimplemented!("This method was not implemented"); + } + fn follows(&self, uri: Cow<'static, str>) -> Result { + unimplemented!("This method was not implemented"); + } + fn media(&self, file: Cow<'static, str>) -> Result { + unimplemented!("This method was not implemented"); + } + fn clear_notifications(&self) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_account(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn follow(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn unfollow(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn block(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn unblock(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn mute(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn unmute(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_notification(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_status(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_context(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_card(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn reblog(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn unreblog(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn favourite(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn unfavourite(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn delete_status(&self, id: u64) -> Result { + unimplemented!("This method was not implemented"); + } + fn update_credentials(&self, changes: CredientialsBuilder) -> Result { + unimplemented!("This method was not implemented"); + } + fn new_status(&self, status: StatusBuilder) -> Result { + unimplemented!("This method was not implemented"); + } + fn get_public_timeline(&self, local: bool) -> Result> { + unimplemented!("This method was not implemented"); + } + fn get_tagged_timeline(&self, hashtag: String, local: bool) -> Result> { + unimplemented!("This method was not implemented"); + } + fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result> + where + S: Into>>, + { + unimplemented!("This method was not implemented"); + } + fn relationships(&self, ids: &[&str]) -> Result> { + unimplemented!("This method was not implemented"); + } + fn search_accounts( + &self, + query: &str, + limit: Option, + following: bool, + ) -> Result> { + unimplemented!("This method was not implemented"); + } } impl Mastodon { @@ -167,12 +277,13 @@ impl From for Mastodon { fn from(data: Data) -> Mastodon { let mut builder = MastodonBuilder::new(); builder.data(data); - builder.build().expect("We know `data` is present, so this should be fine") + builder + .build() + .expect("We know `data` is present, so this should be fine") } } impl MastodonClient for Mastodon { - paged_routes! { (get) favourites: "favourites" => Status, (get) blocks: "blocks" => Account, @@ -225,12 +336,11 @@ impl MastodonClient for Mastodon { (delete) delete_status: "statuses/{}" => Empty, } - fn update_credentials(&self, changes: CredientialsBuilder) - -> Result - { - + fn update_credentials(&self, changes: CredientialsBuilder) -> Result { let url = self.route("/api/v1/accounts/update_credentials"); - let response = self.client.patch(&url) + let response = self + .client + .patch(&url) .headers(self.headers.clone()) .multipart(changes.into_form()?) .send()?; @@ -248,8 +358,9 @@ impl MastodonClient for Mastodon { /// Post a new status to the account. fn new_status(&self, status: StatusBuilder) -> Result { - - let response = self.client.post(&self.route("/api/v1/statuses")) + let response = self + .client + .post(&self.route("/api/v1/statuses")) .headers(self.headers.clone()) .json(&status) .send()?; @@ -317,14 +428,14 @@ impl MastodonClient for Mastodon { /// # token: "".into(), /// # }; /// let client = Mastodon::from(data); - /// let request = StatusesRequest::default() - /// .only_media(); + /// let request = StatusesRequest::default().only_media(); /// let statuses = client.statuses("user-id", request)?; /// # Ok(()) /// # } /// ``` fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result> - where S: Into>> + where + S: Into>>, { let mut url = format!("{}/api/v1/accounts/{}/statuses", self.base, id); @@ -332,9 +443,7 @@ impl MastodonClient for Mastodon { url = format!("{}{}", url, request.to_querystring()); } - let response = self.client.get(&url) - .headers(self.headers.clone()) - .send()?; + let response = self.client.get(&url).headers(self.headers.clone()).send()?; Page::new(self, response) } @@ -356,9 +465,7 @@ impl MastodonClient for Mastodon { url.pop(); } - let response = self.client.get(&url) - .headers(self.headers.clone()) - .send()?; + let response = self.client.get(&url).headers(self.headers.clone()).send()?; Page::new(self, response) } @@ -366,21 +473,21 @@ impl MastodonClient for 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. - fn search_accounts(&self, - query: &str, - limit: Option, - following: bool) - -> Result> - { - let url = format!("{}/api/v1/accounts/search?q={}&limit={}&following={}", - self.base, - query, - limit.unwrap_or(40), - following); - - let response = self.client.get(&url) - .headers(self.headers.clone()) - .send()?; + fn search_accounts( + &self, + query: &str, + limit: Option, + following: bool, + ) -> Result> { + let url = format!( + "{}/api/v1/accounts/search?q={}&limit={}&following={}", + self.base, + query, + limit.unwrap_or(40), + following + ); + + let response = self.client.get(&url).headers(self.headers.clone()).send()?; Page::new(self, response) } @@ -421,12 +528,14 @@ impl MastodonBuilder { pub fn build(self) -> Result { Ok(if let Some(data) = self.data { let mut headers = Headers::new(); - headers.set(Authorization(Bearer { token: (*data.token).to_owned() })); + headers.set(Authorization(Bearer { + token: (*data.token).to_owned(), + })); Mastodon { client: self.client.unwrap_or_else(|| Client::new()), - headers: headers, - data: data, + headers, + data, } } else { return Err(Error::DataMissing); @@ -436,9 +545,7 @@ impl MastodonBuilder { // Convert the HTTP response body from JSON. Pass up deserialization errors // transparently. -fn deserialise serde::Deserialize<'de>>(mut response: Response) - -> Result -{ +fn deserialise serde::Deserialize<'de>>(mut response: Response) -> Result { use std::io::Read; let mut vec = Vec::new(); diff --git a/src/macros.rs b/src/macros.rs index 3b0e2a7..f3347cc 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -165,5 +165,3 @@ macro_rules! paged_routes_with_id { route!{$($rest)*} }; } - - diff --git a/src/page.rs b/src/page.rs index 9b61362..93d39e3 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,9 +1,11 @@ -use super::{Mastodon, Result, deserialise}; -use reqwest::Response; -use reqwest::header::{Link, RelationType}; +use super::{deserialise, Mastodon, Result}; +use entities::itemsiter::ItemsIter; +use reqwest::{ + header::{Link, RelationType}, + Response, +}; use serde::Deserialize; use url::Url; -use entities::itemsiter::ItemsIter; pub struct Page<'a, T: for<'de> Deserialize<'de>> { mastodon: &'a Mastodon, @@ -38,29 +40,32 @@ macro_rules! pages { } impl<'a, T: for<'de> Deserialize<'de>> Page<'a, T> { + pages! { + next: next_page, + prev: prev_page + } + pub fn new(mastodon: &'a Mastodon, response: Response) -> Result { let (prev, next) = get_links(&response)?; Ok(Page { initial_items: deserialise(response)?, next, prev, - mastodon + mastodon, }) } - - pages! { - next: next_page, - prev: prev_page - } } impl<'a, T: Clone + for<'de> Deserialize<'de>> Page<'a, T> { /// Returns an iterator that provides a stream of `T`s /// - /// This abstracts away the process of iterating over each item in a page, then making an http - /// call, then iterating over each item in the new page, etc. The iterator provides a stream of - /// `T`s, calling `self.next_page()` when necessary to get more of them, until there are no more - /// items. + /// This abstracts away the process of iterating over each item in a page, + /// then making an http call, then iterating over each item in the new + /// page, etc. The iterator provides a stream of `T`s, calling + /// `self.next_page()` + /// when necessary to get + /// more of them, until + /// there are no more items. /// /// # Example /// @@ -86,7 +91,8 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>> Page<'a, T> { /// # } /// ``` pub fn items_iter(self) -> impl Iterator + 'a - where T: 'a + where + T: 'a, { ItemsIter::new(self) } diff --git a/src/registration.rs b/src/registration.rs index df2ef20..060bc68 100644 --- a/src/registration.rs +++ b/src/registration.rs @@ -1,8 +1,12 @@ use reqwest::Client; use try_from::TryInto; -use {Data, Error, Mastodon, MastodonBuilder, Result}; use apps::{App, Scopes}; +use Data; +use Error; +use Mastodon; +use MastodonBuilder; +use Result; /// Handles registering your mastodon app to your instance. It is recommended /// you cache your data struct to avoid registering on every run. @@ -47,8 +51,7 @@ impl Registration { /// ```no_run /// # extern crate elefren; /// # fn main () -> elefren::Result<()> { - /// use elefren::prelude::*; - /// use elefren::apps::prelude::*; + /// use elefren::{apps::prelude::*, prelude::*}; /// /// let mut builder = App::builder(); /// builder.client_name("elefren_test"); @@ -67,15 +70,12 @@ impl Registration { /// # } /// ``` pub fn register>(self, app: I) -> Result - where Error: From<>::Err> + where + Error: From<>::Err>, { let app = app.try_into()?; let url = format!("{}/api/v1/apps", self.base); - let oauth: OAuth = self.client - .post(&url) - .form(&app) - .send()? - .json()?; + let oauth: OAuth = self.client.post(&url).form(&app).send()?.json()?; Ok(Registered { base: self.base, @@ -94,10 +94,7 @@ impl Registered { pub fn authorize_url(&self) -> Result { let url = format!( "{}/oauth/authorize?client_id={}&redirect_uri={}&scope={}&response_type=code", - self.base, - self.client_id, - self.redirect, - self.scopes, + self.base, self.client_id, self.redirect, self.scopes, ); Ok(url) diff --git a/src/requests/statuses.rs b/src/requests/statuses.rs index 52a0c18..e80e8f1 100644 --- a/src/requests/statuses.rs +++ b/src/requests/statuses.rs @@ -5,10 +5,7 @@ use std::borrow::Cow; /// ``` /// # extern crate elefren; /// # use elefren::StatusesRequest; -/// let request = StatusesRequest::new() -/// .only_media() -/// .pinned() -/// .since_id("foo"); +/// let request = StatusesRequest::new().only_media().pinned().since_id("foo"); /// # assert_eq!(&request.to_querystring()[..], "?only_media=1&pinned=1&since_id=foo"); /// ``` #[derive(Clone, Debug, Default)] @@ -90,5 +87,3 @@ impl<'a> StatusesRequest<'a> { } } } - - diff --git a/src/status_builder.rs b/src/status_builder.rs index fdfceff..dfb9acc 100644 --- a/src/status_builder.rs +++ b/src/status_builder.rs @@ -4,19 +4,19 @@ pub struct StatusBuilder { /// The text of the status. pub status: String, /// Ids of accounts being replied to. - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub in_reply_to_id: Option, /// Ids of media attachments being attached to the status. - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub media_ids: Option>, /// Whether current status is sensitive. - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub sensitive: Option, /// Text to precede the normal status text. - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub spoiler_text: Option, /// Visibility of the status, defaults to `Public`. - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub visibility: Option, } @@ -38,7 +38,6 @@ pub enum Visibility { } impl StatusBuilder { - /// Create a new status with text. /// ``` /// use elefren::prelude::*; @@ -47,7 +46,7 @@ impl StatusBuilder { /// ``` pub fn new(status: String) -> Self { StatusBuilder { - status: status, + status, ..Self::default() } }