diff --git a/Cargo.toml b/Cargo.toml index 0032201..7e54b24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mammut" -version = "0.1.0" +version = "0.2.0" description = "A wrapper around the Mastodon API." authors = ["Aaron Power "] license = "MIT/Apache-2.0" diff --git a/src/apps.rs b/src/apps.rs index a6e251b..787e770 100644 --- a/src/apps.rs +++ b/src/apps.rs @@ -1,3 +1,12 @@ +/// Builder struct for defining your application. +/// ``` +/// let app = AppBuilder { +/// client_name: "mammut_test", +/// redirect_uris: "urn:ietf:wg:oauth:2.0:oob", +/// scopes: Scope::Read, +/// website: None, +/// }; +/// ``` #[derive(Debug, Default, Serialize)] pub struct AppBuilder<'a> { pub client_name: &'a str, @@ -9,10 +18,13 @@ pub struct AppBuilder<'a> { #[derive(Debug, Clone, Copy, Serialize)] pub enum Scope { + /// All Permissions, equiavlent to `read write follow` #[serde(rename = "read write follow")] All, + /// Only permission to add and remove followers. #[serde(rename = "follow")] Follow, + /// Read only permissions. #[serde(rename = "read")] Read, #[serde(rename = "read follow")] diff --git a/src/lib.rs b/src/lib.rs index c0f1824..c4ab9a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ //! //! Most of the api is documented on [Mastodon's //! github](https://github.com/tootsuite/mastodon/blob/master/docs/Using-the-API/API.md#tag) -#![deny(unused_must_use)] #[cfg_attr(test, deny(warnings))] @@ -12,8 +11,11 @@ extern crate chrono; extern crate reqwest; extern crate serde; +/// Registering your App pub mod apps; +/// Constructing a status pub mod status_builder; +/// Entities returned from the API pub mod entities; use json::Error as SerdeError; @@ -44,7 +46,12 @@ macro_rules! methods { macro_rules! route { ((post ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => { - /// Requires `access_token` or will return error. + /// Equivalent to `/api/v1/ + #[doc = $url] + /// ` + /// + #[doc = "# Errors"] + /// If `access_token` is not set. pub fn $name(&self, $($param: $typ,)*) -> Result<$ret> { self.has_access_token()?; @@ -64,7 +71,12 @@ macro_rules! route { }; (($method:ident) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => { - /// Requires `access_token` or will return error. + /// Equivalent to `/api/v1/ + #[doc = $url] + /// ` + /// + #[doc = "# Errors"] + /// If `access_token` is not set. pub fn $name(&self) -> Result<$ret> { self.has_access_token()?; @@ -81,7 +93,12 @@ macro_rules! route_id { ($(($method:ident) $name:ident: $url:expr => $ret:ty,)*) => { $( - /// Requires `access_token` or will return error. + /// Equivalent to `/api/v1/ + #[doc = $url] + /// ` + /// + #[doc = "# Errors"] + /// If `access_token` is not set. pub fn $name(&self, id: u64) -> Result<$ret> { self.has_access_token()?; @@ -112,6 +129,11 @@ struct OAuth { redirect_uri: String, } +#[derive(Deserialize)] +struct AccessToken { + access_token: String, +} + #[derive(Debug)] pub enum Error { Serde(SerdeError), @@ -194,8 +216,27 @@ impl Mastodon { Ok(url) } + /// Requires the authorisation code returned from the `redirect_url` + pub fn get_access_token(&mut self, code: String) -> Result<()> { + self.is_registered()?; + + let url = format!( + "{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&redirect_uri={}", + self.base_url, + self.client_id.clone().unwrap(), + self.client_secret.clone().unwrap(), + code, + self.redirect_uri.clone().unwrap(), + ); + + let access_token: AccessToken = self.client.post(&url).send()?.json()?; + + self.set_access_token(access_token.access_token); + Ok(()) + } + /// Set `access_token` required to use any method about the user. - pub fn set_access_token(&mut self, access_token: String) { + fn set_access_token(&mut self, access_token: String) { let mut headers = Headers::new(); headers.set(Authorization(Bearer { token: access_token })); diff --git a/src/status_builder.rs b/src/status_builder.rs index 054c12f..aafd9a6 100644 --- a/src/status_builder.rs +++ b/src/status_builder.rs @@ -1,26 +1,31 @@ #[derive(Debug, Default, Clone, Serialize)] pub struct StatusBuilder { status: String, + /// User ids of those to reply to. #[serde(skip_serializing_if="Option::is_none")] - in_reply_to_id: Option, + pub in_reply_to_id: Option, #[serde(skip_serializing_if="Option::is_none")] - media_ids: Option>, + pub media_ids: Option>, #[serde(skip_serializing_if="Option::is_none")] - sensitive: Option, + pub sensitive: Option, #[serde(skip_serializing_if="Option::is_none")] - spoiler_text: Option, + pub spoiler_text: Option, #[serde(skip_serializing_if="Option::is_none")] - visibility: Option, + pub visibility: Option, } #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub enum Visibility { + /// A Direct message to a user #[serde(rename = "direct")] Direct, + /// Only available to followers #[serde(rename = "private")] Private, + /// Not shown in public timelines #[serde(rename = "unlisted")] Unlisted, + /// Posted to public timelines #[serde(rename = "public")] Public, }