forked from MightyPork/elefren-fork
Remove HttpSend and HttpSender
this was maybe a good idea, but it isn't really needed
This commit is contained in:
@@ -76,7 +76,7 @@ use elefren::entities::event::Event;
|
|||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let data = Data {
|
let data = Data {
|
||||||
base: "".into(),
|
base: "".into(),
|
||||||
client_id: "".into(),
|
client_id: "".into(),
|
||||||
|
|||||||
+2
-2
@@ -61,7 +61,7 @@ impl App {
|
|||||||
/// use elefren::apps::App;
|
/// use elefren::apps::App;
|
||||||
/// use std::error::Error;
|
/// use std::error::Error;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let mut builder = App::builder();
|
/// let mut builder = App::builder();
|
||||||
/// builder.client_name("elefren_test");
|
/// builder.client_name("elefren_test");
|
||||||
/// let app = builder.build()?;
|
/// let app = builder.build()?;
|
||||||
@@ -120,7 +120,7 @@ impl<'a> AppBuilder<'a> {
|
|||||||
Ok(App {
|
Ok(App {
|
||||||
client_name: self
|
client_name: self
|
||||||
.client_name
|
.client_name
|
||||||
.ok_or_else(|| Error::MissingField("client_name"))?
|
.ok_or(Error::MissingField("client_name"))?
|
||||||
.into(),
|
.into(),
|
||||||
redirect_uris: self
|
redirect_uris: self
|
||||||
.redirect_uris
|
.redirect_uris
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{http_send::HttpSend, page::Page};
|
use crate::page::Page;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
/// Abstracts away the `next_page` logic into a single stream of items
|
/// Abstracts away the `next_page` logic into a single stream of items
|
||||||
@@ -7,7 +7,7 @@ use serde::Deserialize;
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -24,15 +24,15 @@ use serde::Deserialize;
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ItemsIter<'a, T: Clone + for<'de> Deserialize<'de>, H: 'a + HttpSend> {
|
pub(crate) struct ItemsIter<'a, T: Clone + for<'de> Deserialize<'de>> {
|
||||||
page: Page<'a, T, H>,
|
page: Page<'a, T>,
|
||||||
buffer: Vec<T>,
|
buffer: Vec<T>,
|
||||||
cur_idx: usize,
|
cur_idx: usize,
|
||||||
use_initial: bool,
|
use_initial: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> ItemsIter<'a, T, H> {
|
impl<'a, T: Clone + for<'de> Deserialize<'de>> ItemsIter<'a, T> {
|
||||||
pub(crate) fn new(page: Page<'a, T, H>) -> ItemsIter<'a, T, H> {
|
pub(crate) fn new(page: Page<'a, T>) -> ItemsIter<'a, T> {
|
||||||
ItemsIter {
|
ItemsIter {
|
||||||
page,
|
page,
|
||||||
buffer: vec![],
|
buffer: vec![],
|
||||||
@@ -64,7 +64,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> ItemsIter<'a, T, H>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Iterator for ItemsIter<'a, T, H> {
|
impl<'a, T: Clone + for<'de> Deserialize<'de>> Iterator for ItemsIter<'a, T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
use std::io::{self, BufRead, Write};
|
use std::io::{self, BufRead, Write};
|
||||||
|
|
||||||
use crate::{errors::Result, http_send::HttpSend, registration::Registered, Mastodon};
|
use crate::{errors::Result, registration::Registered, Mastodon};
|
||||||
|
|
||||||
/// Finishes the authentication process for the given `Registered` object,
|
/// Finishes the authentication process for the given `Registered` object,
|
||||||
/// using the command-line
|
/// using the command-line
|
||||||
pub fn authenticate<H: HttpSend>(registration: Registered<H>) -> Result<Mastodon<H>> {
|
pub fn authenticate(registration: Registered) -> Result<Mastodon> {
|
||||||
let url = registration.authorize_url()?;
|
let url = registration.authorize_url()?;
|
||||||
|
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
use crate::Result;
|
|
||||||
use reqwest::{Client, Request, RequestBuilder, Response};
|
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
/// Abstracts away the process of turning an HTTP request into an HTTP response
|
|
||||||
pub trait HttpSend: Clone + Debug {
|
|
||||||
/// Converts an HTTP request into an HTTP response
|
|
||||||
fn execute(&self, client: &Client, request: Request) -> Result<Response>;
|
|
||||||
|
|
||||||
/// Convenience method so that .build() doesn't have to be called at every
|
|
||||||
/// call site
|
|
||||||
fn send(&self, client: &Client, builder: RequestBuilder) -> Result<Response> {
|
|
||||||
let request = builder.build()?;
|
|
||||||
self.execute(client, request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub struct HttpSender;
|
|
||||||
|
|
||||||
impl HttpSend for HttpSender {
|
|
||||||
fn execute(&self, client: &Client, request: Request) -> Result<Response> {
|
|
||||||
Ok(client.execute(request)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+30
-42
@@ -36,7 +36,7 @@
|
|||||||
//! # use elefren::prelude::*;
|
//! # use elefren::prelude::*;
|
||||||
//! # use std::error::Error;
|
//! # use std::error::Error;
|
||||||
//! use elefren::entities::event::Event;
|
//! use elefren::entities::event::Event;
|
||||||
//! # fn main() -> Result<(), Box<Error>> {
|
//! # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
//! # let data = Data {
|
//! # let data = Data {
|
||||||
//! # base: "".into(),
|
//! # base: "".into(),
|
||||||
//! # client_id: "".into(),
|
//! # client_id: "".into(),
|
||||||
@@ -77,11 +77,7 @@ use reqwest::{Client, RequestBuilder, Response};
|
|||||||
use tap_reader::Tap;
|
use tap_reader::Tap;
|
||||||
use tungstenite::client::AutoStream;
|
use tungstenite::client::AutoStream;
|
||||||
|
|
||||||
use crate::{
|
use crate::{entities::prelude::*, page::Page};
|
||||||
entities::prelude::*,
|
|
||||||
http_send::{HttpSend, HttpSender},
|
|
||||||
page::Page,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
data::Data,
|
data::Data,
|
||||||
@@ -110,8 +106,6 @@ pub mod entities;
|
|||||||
pub mod errors;
|
pub mod errors;
|
||||||
/// Collection of helpers for serializing/deserializing `Data` objects
|
/// Collection of helpers for serializing/deserializing `Data` objects
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
/// Contains trait for converting `reqwest::Request`s to `reqwest::Response`s
|
|
||||||
pub mod http_send;
|
|
||||||
mod mastodon_client;
|
mod mastodon_client;
|
||||||
/// Constructing media attachments for a status.
|
/// Constructing media attachments for a status.
|
||||||
pub mod media_builder;
|
pub mod media_builder;
|
||||||
@@ -143,14 +137,13 @@ pub mod prelude {
|
|||||||
|
|
||||||
/// 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<H: HttpSend = HttpSender> {
|
pub struct Mastodon {
|
||||||
client: Client,
|
client: Client,
|
||||||
http_sender: H,
|
|
||||||
/// Raw data about your mastodon instance.
|
/// Raw data about your mastodon instance.
|
||||||
pub data: Data,
|
pub data: Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> Mastodon<H> {
|
impl Mastodon {
|
||||||
methods![get, post, delete,];
|
methods![get, post, delete,];
|
||||||
|
|
||||||
fn route(&self, url: &str) -> String {
|
fn route(&self, url: &str) -> String {
|
||||||
@@ -158,16 +151,15 @@ impl<H: HttpSend> Mastodon<H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn send(&self, req: RequestBuilder) -> Result<Response> {
|
pub(crate) fn send(&self, req: RequestBuilder) -> Result<Response> {
|
||||||
Ok(self
|
let request = req.bearer_auth(&self.token).build()?;
|
||||||
.http_sender
|
Ok(self.client.execute(request)?)
|
||||||
.send(&self.client, req.bearer_auth(&self.token))?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Data> for Mastodon<HttpSender> {
|
impl From<Data> for Mastodon {
|
||||||
/// Creates a mastodon instance from the data struct.
|
/// Creates a mastodon instance from the data struct.
|
||||||
fn from(data: Data) -> Mastodon<HttpSender> {
|
fn from(data: Data) -> Mastodon {
|
||||||
let mut builder = MastodonBuilder::new(HttpSender);
|
let mut builder = MastodonBuilder::new();
|
||||||
builder.data(data);
|
builder.data(data);
|
||||||
builder
|
builder
|
||||||
.build()
|
.build()
|
||||||
@@ -175,7 +167,7 @@ impl From<Data> for Mastodon<HttpSender> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
impl MastodonClient for Mastodon {
|
||||||
type Stream = EventReader<WebSocket>;
|
type Stream = EventReader<WebSocket>;
|
||||||
|
|
||||||
paged_routes! {
|
paged_routes! {
|
||||||
@@ -307,7 +299,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
|
|
||||||
/// 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, H>> {
|
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))
|
||||||
@@ -327,7 +319,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -345,7 +337,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -360,7 +352,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status, H>>
|
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>>>,
|
||||||
{
|
{
|
||||||
@@ -377,7 +369,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
|
|
||||||
/// 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, H>> {
|
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 {
|
||||||
@@ -423,13 +415,13 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get all accounts that follow the authenticated user
|
/// Get all accounts that follow the authenticated user
|
||||||
fn follows_me(&self) -> Result<Page<Account, H>> {
|
fn follows_me(&self) -> Result<Page<Account>> {
|
||||||
let me = self.verify_credentials()?;
|
let me = self.verify_credentials()?;
|
||||||
Ok(self.followers(&me.id)?)
|
Ok(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, H>> {
|
fn followed_by_me(&self) -> Result<Page<Account>> {
|
||||||
let me = self.verify_credentials()?;
|
let me = self.verify_credentials()?;
|
||||||
Ok(self.following(&me.id)?)
|
Ok(self.following(&me.id)?)
|
||||||
}
|
}
|
||||||
@@ -444,7 +436,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::entities::event::Event;
|
/// use elefren::entities::event::Event;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -737,7 +729,7 @@ impl<R: EventStream> EventReader<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> ops::Deref for Mastodon<H> {
|
impl ops::Deref for Mastodon {
|
||||||
type Target = Data;
|
type Target = Data;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@@ -745,16 +737,14 @@ impl<H: HttpSend> ops::Deref for Mastodon<H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MastodonBuilder<H: HttpSend> {
|
struct MastodonBuilder {
|
||||||
client: Option<Client>,
|
client: Option<Client>,
|
||||||
http_sender: H,
|
|
||||||
data: Option<Data>,
|
data: Option<Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> MastodonBuilder<H> {
|
impl MastodonBuilder {
|
||||||
pub fn new(sender: H) -> Self {
|
pub fn new() -> Self {
|
||||||
MastodonBuilder {
|
MastodonBuilder {
|
||||||
http_sender: sender,
|
|
||||||
client: None,
|
client: None,
|
||||||
data: None,
|
data: None,
|
||||||
}
|
}
|
||||||
@@ -770,11 +760,10 @@ impl<H: HttpSend> MastodonBuilder<H> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<Mastodon<H>> {
|
pub fn build(self) -> Result<Mastodon> {
|
||||||
Ok(if let Some(data) = self.data {
|
Ok(if let Some(data) = self.data {
|
||||||
Mastodon {
|
Mastodon {
|
||||||
client: self.client.unwrap_or_else(Client::new),
|
client: self.client.unwrap_or_else(Client::new),
|
||||||
http_sender: self.http_sender,
|
|
||||||
data,
|
data,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -785,15 +774,14 @@ impl<H: HttpSend> MastodonBuilder<H> {
|
|||||||
|
|
||||||
/// Client that can make unauthenticated calls to a mastodon instance
|
/// Client that can make unauthenticated calls to a mastodon instance
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MastodonUnauth<H: HttpSend = HttpSender> {
|
pub struct MastodonUnauth {
|
||||||
client: Client,
|
client: Client,
|
||||||
http_sender: H,
|
|
||||||
base: url::Url,
|
base: url::Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MastodonUnauth<HttpSender> {
|
impl MastodonUnauth {
|
||||||
/// Create a new unauthenticated client
|
/// Create a new unauthenticated client
|
||||||
pub fn new(base: &str) -> Result<MastodonUnauth<HttpSender>> {
|
pub fn new(base: &str) -> Result<MastodonUnauth> {
|
||||||
let base = if base.starts_with("https://") {
|
let base = if base.starts_with("https://") {
|
||||||
base.to_string()
|
base.to_string()
|
||||||
} else {
|
} else {
|
||||||
@@ -801,19 +789,19 @@ impl MastodonUnauth<HttpSender> {
|
|||||||
};
|
};
|
||||||
Ok(MastodonUnauth {
|
Ok(MastodonUnauth {
|
||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
http_sender: HttpSender,
|
|
||||||
base: url::Url::parse(&base)?,
|
base: url::Url::parse(&base)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> MastodonUnauth<H> {
|
impl MastodonUnauth {
|
||||||
fn route(&self, url: &str) -> Result<url::Url> {
|
fn route(&self, url: &str) -> Result<url::Url> {
|
||||||
Ok(self.base.join(url)?)
|
Ok(self.base.join(url)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
||||||
Ok(self.http_sender.send(&self.client, req)?)
|
let req = req.build()?;
|
||||||
|
Ok(self.client.execute(req)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a stream of the public timeline
|
/// Get a stream of the public timeline
|
||||||
@@ -835,7 +823,7 @@ impl<H: HttpSend> MastodonUnauth<H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> MastodonUnauthenticated<H> for MastodonUnauth<H> {
|
impl MastodonUnauthenticated for MastodonUnauth {
|
||||||
/// GET /api/v1/statuses/:id
|
/// GET /api/v1/statuses/:id
|
||||||
fn get_status(&self, id: &str) -> Result<Status> {
|
fn get_status(&self, id: &str) -> Result<Status> {
|
||||||
let route = self.route("/api/v1/statuses")?;
|
let route = self.route("/api/v1/statuses")?;
|
||||||
|
|||||||
+3
-3
@@ -40,7 +40,7 @@ macro_rules! paged_routes {
|
|||||||
"# }\n",
|
"# }\n",
|
||||||
"```"
|
"```"
|
||||||
),
|
),
|
||||||
fn $name(&self) -> Result<Page<$ret, H>> {
|
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)
|
||||||
@@ -61,7 +61,7 @@ macro_rules! paged_routes {
|
|||||||
$url,
|
$url,
|
||||||
"`\n# Errors\nIf `access_token` is not set."
|
"`\n# Errors\nIf `access_token` is not set."
|
||||||
),
|
),
|
||||||
fn $name<'a>(&self, $($param: $typ,)*) -> Result<Page<$ret, H>> {
|
fn $name<'a>(&self, $($param: $typ,)*) -> Result<Page<$ret>> {
|
||||||
use serde_urlencoded;
|
use serde_urlencoded;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ macro_rules! paged_routes_with_id {
|
|||||||
"# }\n",
|
"# }\n",
|
||||||
"```"
|
"```"
|
||||||
),
|
),
|
||||||
fn $name(&self, id: &str) -> Result<Page<$ret, H>> {
|
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)
|
||||||
|
|||||||
+28
-29
@@ -3,7 +3,6 @@ use std::borrow::Cow;
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::prelude::*,
|
entities::prelude::*,
|
||||||
errors::Result,
|
errors::Result,
|
||||||
http_send::{HttpSend, HttpSender},
|
|
||||||
media_builder::MediaBuilder,
|
media_builder::MediaBuilder,
|
||||||
page::Page,
|
page::Page,
|
||||||
requests::{
|
requests::{
|
||||||
@@ -19,60 +18,60 @@ use crate::{
|
|||||||
/// Represents the set of methods that a Mastodon Client can do, so that
|
/// Represents the set of methods that a Mastodon Client can do, so that
|
||||||
/// implementations might be swapped out for testing
|
/// implementations might be swapped out for testing
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub trait MastodonClient<H: HttpSend = HttpSender> {
|
pub trait MastodonClient {
|
||||||
/// Type that wraps streaming API streams
|
/// Type that wraps streaming API streams
|
||||||
type Stream: Iterator<Item = Event>;
|
type Stream: Iterator<Item = Event>;
|
||||||
|
|
||||||
/// GET /api/v1/favourites
|
/// GET /api/v1/favourites
|
||||||
fn favourites(&self) -> Result<Page<Status, H>> {
|
fn favourites(&self) -> Result<Page<Status>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/blocks
|
/// GET /api/v1/blocks
|
||||||
fn blocks(&self) -> Result<Page<Account, H>> {
|
fn blocks(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/domain_blocks
|
/// GET /api/v1/domain_blocks
|
||||||
fn domain_blocks(&self) -> Result<Page<String, H>> {
|
fn domain_blocks(&self) -> Result<Page<String>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/follow_requests
|
/// GET /api/v1/follow_requests
|
||||||
fn follow_requests(&self) -> Result<Page<Account, H>> {
|
fn follow_requests(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/timelines/home
|
/// GET /api/v1/timelines/home
|
||||||
fn get_home_timeline(&self) -> Result<Page<Status, H>> {
|
fn get_home_timeline(&self) -> Result<Page<Status>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/custom_emojis
|
/// GET /api/v1/custom_emojis
|
||||||
fn get_emojis(&self) -> Result<Page<Emoji, H>> {
|
fn get_emojis(&self) -> Result<Page<Emoji>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/mutes
|
/// GET /api/v1/mutes
|
||||||
fn mutes(&self) -> Result<Page<Account, H>> {
|
fn mutes(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/notifications
|
/// GET /api/v1/notifications
|
||||||
fn notifications(&self) -> Result<Page<Notification, H>> {
|
fn notifications(&self) -> Result<Page<Notification>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/reports
|
/// GET /api/v1/reports
|
||||||
fn reports(&self) -> Result<Page<Report, H>> {
|
fn reports(&self) -> Result<Page<Report>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/accounts/:id/followers
|
/// GET /api/v1/accounts/:id/followers
|
||||||
fn followers(&self, id: &str) -> Result<Page<Account, H>> {
|
fn followers(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/accounts/:id/following
|
/// GET /api/v1/accounts/:id/following
|
||||||
fn following(&self, id: &str) -> Result<Page<Account, H>> {
|
fn following(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/statuses/:id/reblogged_by
|
/// GET /api/v1/statuses/:id/reblogged_by
|
||||||
fn reblogged_by(&self, id: &str) -> Result<Page<Account, H>> {
|
fn reblogged_by(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/statuses/:id/favourited_by
|
/// GET /api/v1/statuses/:id/favourited_by
|
||||||
fn favourited_by(&self, id: &str) -> Result<Page<Account, H>> {
|
fn favourited_by(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// DELETE /api/v1/domain_blocks
|
/// DELETE /api/v1/domain_blocks
|
||||||
@@ -200,26 +199,26 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/timelines/public?local=true
|
/// GET /api/v1/timelines/public?local=true
|
||||||
fn get_local_timeline(&self) -> Result<Page<Status, H>> {
|
fn get_local_timeline(&self) -> Result<Page<Status>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/timelines/public?local=false
|
/// GET /api/v1/timelines/public?local=false
|
||||||
fn get_federated_timeline(&self) -> Result<Page<Status, H>> {
|
fn get_federated_timeline(&self) -> Result<Page<Status>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/timelines/tag/:hashtag
|
/// GET /api/v1/timelines/tag/:hashtag
|
||||||
fn get_hashtag_timeline(&self, hashtag: &str, local: bool) -> Result<Page<Status, H>> {
|
fn get_hashtag_timeline(&self, hashtag: &str, local: bool) -> Result<Page<Status>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/accounts/:id/statuses
|
/// GET /api/v1/accounts/:id/statuses
|
||||||
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status, H>>
|
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>>>,
|
||||||
{
|
{
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/accounts/relationships
|
/// GET /api/v1/accounts/relationships
|
||||||
fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship, H>> {
|
fn relationships(&self, ids: &[&str]) -> Result<Page<Relationship>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/accounts/search?q=:query&limit=:limit&following=:following
|
/// GET /api/v1/accounts/search?q=:query&limit=:limit&following=:following
|
||||||
@@ -228,7 +227,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
query: &str,
|
query: &str,
|
||||||
limit: Option<u64>,
|
limit: Option<u64>,
|
||||||
following: bool,
|
following: bool,
|
||||||
) -> Result<Page<Account, H>> {
|
) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// POST /api/v1/push/subscription
|
/// POST /api/v1/push/subscription
|
||||||
@@ -276,7 +275,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/endorsements
|
/// GET /api/v1/endorsements
|
||||||
fn get_endorsements(&self) -> Result<Page<Account, H>> {
|
fn get_endorsements(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// POST /api/v1/accounts/:id/pin
|
/// POST /api/v1/accounts/:id/pin
|
||||||
@@ -293,7 +292,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -305,7 +304,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
/// let follows_me = client.follows_me()?;
|
/// let follows_me = client.follows_me()?;
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
fn follows_me(&self) -> Result<Page<Account, H>> {
|
fn follows_me(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// Shortcut for
|
/// Shortcut for
|
||||||
@@ -315,7 +314,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
@@ -327,7 +326,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
/// let follows_me = client.followed_by_me()?;
|
/// let follows_me = client.followed_by_me()?;
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
fn followed_by_me(&self) -> Result<Page<Account, H>> {
|
fn followed_by_me(&self) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +370,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
/// Trait that represents clients that can make unauthenticated calls to a
|
/// Trait that represents clients that can make unauthenticated calls to a
|
||||||
/// mastodon instance
|
/// mastodon instance
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub trait MastodonUnauthenticated<H: HttpSend> {
|
pub trait MastodonUnauthenticated {
|
||||||
/// GET /api/v1/statuses/:id
|
/// GET /api/v1/statuses/:id
|
||||||
fn get_status(&self, id: &str) -> Result<Status> {
|
fn get_status(&self, id: &str) -> Result<Status> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
@@ -385,11 +384,11 @@ pub trait MastodonUnauthenticated<H: HttpSend> {
|
|||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/statuses/:id/reblogged_by
|
/// GET /api/v1/statuses/:id/reblogged_by
|
||||||
fn reblogged_by(&self, id: &str) -> Result<Page<Account, H>> {
|
fn reblogged_by(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// GET /api/v1/statuses/:id/favourited_by
|
/// GET /api/v1/statuses/:id/favourited_by
|
||||||
fn favourited_by(&self, id: &str) -> Result<Page<Account, H>> {
|
fn favourited_by(&self, id: &str) -> Result<Page<Account>> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-18
@@ -5,8 +5,6 @@ use reqwest::{header::LINK, Response};
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::http_send::HttpSend;
|
|
||||||
|
|
||||||
macro_rules! pages {
|
macro_rules! pages {
|
||||||
($($direction:ident: $fun:ident),*) => {
|
($($direction:ident: $fun:ident),*) => {
|
||||||
|
|
||||||
@@ -42,7 +40,6 @@ macro_rules! pages {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::Mastodon;
|
/// # use elefren::Mastodon;
|
||||||
/// # use elefren::page::OwnedPage;
|
/// # use elefren::page::OwnedPage;
|
||||||
/// # use elefren::http_send::HttpSender;
|
|
||||||
/// # use elefren::entities::status::Status;
|
/// # use elefren::entities::status::Status;
|
||||||
/// # use std::cell::RefCell;
|
/// # use std::cell::RefCell;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
@@ -56,7 +53,7 @@ macro_rules! pages {
|
|||||||
/// # };
|
/// # };
|
||||||
/// struct HomeTimeline {
|
/// struct HomeTimeline {
|
||||||
/// client: Mastodon,
|
/// client: Mastodon,
|
||||||
/// page: RefCell<Option<OwnedPage<Status, HttpSender>>>,
|
/// page: RefCell<Option<OwnedPage<Status>>>,
|
||||||
/// }
|
/// }
|
||||||
/// let client = Mastodon::from(data);
|
/// let client = Mastodon::from(data);
|
||||||
/// let home = client.get_home_timeline()?.into_owned();
|
/// let home = client.get_home_timeline()?.into_owned();
|
||||||
@@ -68,23 +65,23 @@ macro_rules! pages {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OwnedPage<T: for<'de> Deserialize<'de>, H: HttpSend> {
|
pub struct OwnedPage<T: for<'de> Deserialize<'de>> {
|
||||||
mastodon: Mastodon<H>,
|
mastodon: Mastodon,
|
||||||
next: Option<Url>,
|
next: Option<Url>,
|
||||||
prev: Option<Url>,
|
prev: Option<Url>,
|
||||||
/// Initial set of items
|
/// Initial set of items
|
||||||
pub initial_items: Vec<T>,
|
pub initial_items: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: for<'de> Deserialize<'de>, H: HttpSend> OwnedPage<T, H> {
|
impl<T: for<'de> Deserialize<'de>> OwnedPage<T> {
|
||||||
pages! {
|
pages! {
|
||||||
next: next_page,
|
next: next_page,
|
||||||
prev: prev_page
|
prev: prev_page
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: for<'de> Deserialize<'de>, H: HttpSend> From<Page<'a, T, H>> for OwnedPage<T, H> {
|
impl<'a, T: for<'de> Deserialize<'de>> From<Page<'a, T>> for OwnedPage<T> {
|
||||||
fn from(page: Page<'a, T, H>) -> OwnedPage<T, H> {
|
fn from(page: Page<'a, T>) -> OwnedPage<T> {
|
||||||
OwnedPage {
|
OwnedPage {
|
||||||
mastodon: page.mastodon.clone(),
|
mastodon: page.mastodon.clone(),
|
||||||
next: page.next,
|
next: page.next,
|
||||||
@@ -96,21 +93,21 @@ impl<'a, T: for<'de> Deserialize<'de>, H: HttpSend> From<Page<'a, T, H>> for Own
|
|||||||
|
|
||||||
/// Represents a single page of API results
|
/// Represents a single page of API results
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Page<'a, T: for<'de> Deserialize<'de>, H: 'a + HttpSend> {
|
pub struct Page<'a, T: for<'de> Deserialize<'de>> {
|
||||||
mastodon: &'a Mastodon<H>,
|
mastodon: &'a Mastodon,
|
||||||
next: Option<Url>,
|
next: Option<Url>,
|
||||||
prev: Option<Url>,
|
prev: Option<Url>,
|
||||||
/// Initial set of items
|
/// Initial set of items
|
||||||
pub initial_items: Vec<T>,
|
pub initial_items: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
impl<'a, T: for<'de> Deserialize<'de>> Page<'a, T> {
|
||||||
pages! {
|
pages! {
|
||||||
next: next_page,
|
next: next_page,
|
||||||
prev: prev_page
|
prev: prev_page
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(mastodon: &'a Mastodon<H>, response: Response) -> Result<Self> {
|
pub(crate) fn new(mastodon: &'a Mastodon, response: Response) -> Result<Self> {
|
||||||
let (prev, next) = get_links(&response)?;
|
let (prev, next) = get_links(&response)?;
|
||||||
Ok(Page {
|
Ok(Page {
|
||||||
initial_items: deserialise(response)?,
|
initial_items: deserialise(response)?,
|
||||||
@@ -121,7 +118,7 @@ impl<'a, T: for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
impl<'a, T: Clone + for<'de> Deserialize<'de>> Page<'a, T> {
|
||||||
/// Returns an owned version of this struct that doesn't borrow the client
|
/// Returns an owned version of this struct that doesn't borrow the client
|
||||||
/// that created it
|
/// that created it
|
||||||
///
|
///
|
||||||
@@ -131,7 +128,6 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::Mastodon;
|
/// # use elefren::Mastodon;
|
||||||
/// # use elefren::page::OwnedPage;
|
/// # use elefren::page::OwnedPage;
|
||||||
/// # use elefren::http_send::HttpSender;
|
|
||||||
/// # use elefren::entities::status::Status;
|
/// # use elefren::entities::status::Status;
|
||||||
/// # use std::cell::RefCell;
|
/// # use std::cell::RefCell;
|
||||||
/// # use elefren::prelude::*;
|
/// # use elefren::prelude::*;
|
||||||
@@ -145,7 +141,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||||||
/// # };
|
/// # };
|
||||||
/// struct HomeTimeline {
|
/// struct HomeTimeline {
|
||||||
/// client: Mastodon,
|
/// client: Mastodon,
|
||||||
/// page: RefCell<Option<OwnedPage<Status, HttpSender>>>,
|
/// page: RefCell<Option<OwnedPage<Status>>>,
|
||||||
/// }
|
/// }
|
||||||
/// let client = Mastodon::from(data);
|
/// let client = Mastodon::from(data);
|
||||||
/// let home = client.get_home_timeline()?.into_owned();
|
/// let home = client.get_home_timeline()?.into_owned();
|
||||||
@@ -156,7 +152,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn into_owned(self) -> OwnedPage<T, H> {
|
pub fn into_owned(self) -> OwnedPage<T> {
|
||||||
OwnedPage::from(self)
|
OwnedPage::from(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +172,7 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::prelude::*;
|
/// use elefren::prelude::*;
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// # let data = Data {
|
/// # let data = Data {
|
||||||
/// # base: "".into(),
|
/// # base: "".into(),
|
||||||
/// # client_id: "".into(),
|
/// # client_id: "".into(),
|
||||||
|
|||||||
+16
-34
@@ -7,7 +7,6 @@ use url::percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
apps::{App, AppBuilder},
|
apps::{App, AppBuilder},
|
||||||
http_send::{HttpSend, HttpSender},
|
|
||||||
scopes::Scopes,
|
scopes::Scopes,
|
||||||
Data,
|
Data,
|
||||||
Error,
|
Error,
|
||||||
@@ -21,12 +20,11 @@ const DEFAULT_REDIRECT_URI: &str = "urn:ietf:wg:oauth:2.0:oob";
|
|||||||
/// Handles registering your mastodon app to your instance. It is recommended
|
/// Handles registering your mastodon app to your instance. It is recommended
|
||||||
/// you cache your data struct to avoid registering on every run.
|
/// you cache your data struct to avoid registering on every run.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Registration<'a, H: HttpSend = HttpSender> {
|
pub struct Registration<'a> {
|
||||||
base: String,
|
base: String,
|
||||||
client: Client,
|
client: Client,
|
||||||
app_builder: AppBuilder<'a>,
|
app_builder: AppBuilder<'a>,
|
||||||
force_login: bool,
|
force_login: bool,
|
||||||
http_sender: H,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -46,7 +44,7 @@ struct AccessToken {
|
|||||||
access_token: String,
|
access_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Registration<'a, HttpSender> {
|
impl<'a> Registration<'a> {
|
||||||
/// Construct a new registration process to the instance of the `base` url.
|
/// Construct a new registration process to the instance of the `base` url.
|
||||||
/// ```
|
/// ```
|
||||||
/// use elefren::prelude::*;
|
/// use elefren::prelude::*;
|
||||||
@@ -59,23 +57,11 @@ impl<'a> Registration<'a, HttpSender> {
|
|||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
app_builder: AppBuilder::new(),
|
app_builder: AppBuilder::new(),
|
||||||
force_login: false,
|
force_login: false,
|
||||||
http_sender: HttpSender,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, H: HttpSend> Registration<'a, H> {
|
impl<'a> Registration<'a> {
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn with_sender<I: Into<String>>(base: I, http_sender: H) -> Self {
|
|
||||||
Registration {
|
|
||||||
base: base.into(),
|
|
||||||
client: Client::new(),
|
|
||||||
app_builder: AppBuilder::new(),
|
|
||||||
force_login: false,
|
|
||||||
http_sender,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the name of this app
|
/// Sets the name of this app
|
||||||
///
|
///
|
||||||
/// This is required, and if this isn't set then the AppBuilder::build
|
/// This is required, and if this isn't set then the AppBuilder::build
|
||||||
@@ -113,7 +99,8 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
||||||
Ok(self.http_sender.send(&self.client, req)?)
|
let req = req.build()?;
|
||||||
|
Ok(self.client.execute(req)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register the given application
|
/// Register the given application
|
||||||
@@ -137,7 +124,7 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn register<I: TryInto<App>>(&mut self, app: I) -> Result<Registered<H>>
|
pub fn register<I: TryInto<App>>(&mut self, app: I) -> Result<Registered>
|
||||||
where
|
where
|
||||||
Error: From<<I as TryInto<App>>::Err>,
|
Error: From<<I as TryInto<App>>::Err>,
|
||||||
{
|
{
|
||||||
@@ -152,7 +139,6 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
redirect: oauth.redirect_uri,
|
redirect: oauth.redirect_uri,
|
||||||
scopes: app.scopes().clone(),
|
scopes: app.scopes().clone(),
|
||||||
force_login: self.force_login,
|
force_login: self.force_login,
|
||||||
http_sender: self.http_sender.clone(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +162,7 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn build(&mut self) -> Result<Registered<H>> {
|
pub fn build(&mut self) -> Result<Registered> {
|
||||||
let app: App = self.app_builder.clone().build()?;
|
let app: App = self.app_builder.clone().build()?;
|
||||||
let oauth = self.send_app(&app)?;
|
let oauth = self.send_app(&app)?;
|
||||||
|
|
||||||
@@ -188,7 +174,6 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
redirect: oauth.redirect_uri,
|
redirect: oauth.redirect_uri,
|
||||||
scopes: app.scopes().clone(),
|
scopes: app.scopes().clone(),
|
||||||
force_login: self.force_login,
|
force_login: self.force_login,
|
||||||
http_sender: self.http_sender.clone(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +183,7 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Registered<HttpSender> {
|
impl Registered {
|
||||||
/// Skip having to retrieve the client id and secret from the server by
|
/// Skip having to retrieve the client id and secret from the server by
|
||||||
/// creating a `Registered` struct directly
|
/// creating a `Registered` struct directly
|
||||||
///
|
///
|
||||||
@@ -234,7 +219,7 @@ impl Registered<HttpSender> {
|
|||||||
redirect: &str,
|
redirect: &str,
|
||||||
scopes: Scopes,
|
scopes: Scopes,
|
||||||
force_login: bool,
|
force_login: bool,
|
||||||
) -> Registered<HttpSender> {
|
) -> Registered {
|
||||||
Registered {
|
Registered {
|
||||||
base: base.to_string(),
|
base: base.to_string(),
|
||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
@@ -243,14 +228,14 @@ impl Registered<HttpSender> {
|
|||||||
redirect: redirect.to_string(),
|
redirect: redirect.to_string(),
|
||||||
scopes,
|
scopes,
|
||||||
force_login,
|
force_login,
|
||||||
http_sender: HttpSender,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: HttpSend> Registered<H> {
|
impl Registered {
|
||||||
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
fn send(&self, req: RequestBuilder) -> Result<Response> {
|
||||||
Ok(self.http_sender.send(&self.client, req)?)
|
let req = req.build()?;
|
||||||
|
Ok(self.client.execute(req)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the parts of the `Registered` struct that can be used to
|
/// Returns the parts of the `Registered` struct that can be used to
|
||||||
@@ -324,7 +309,7 @@ impl<H: HttpSend> Registered<H> {
|
|||||||
|
|
||||||
/// Create an access token from the client id, client secret, and code
|
/// Create an access token from the client id, client secret, and code
|
||||||
/// provided by the authorisation url.
|
/// provided by the authorisation url.
|
||||||
pub fn complete(&self, code: &str) -> Result<Mastodon<H>> {
|
pub fn complete(&self, code: &str) -> Result<Mastodon> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&\
|
"{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&\
|
||||||
redirect_uri={}",
|
redirect_uri={}",
|
||||||
@@ -341,7 +326,7 @@ impl<H: HttpSend> Registered<H> {
|
|||||||
token: token.access_token.into(),
|
token: token.access_token.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut builder = MastodonBuilder::new(self.http_sender.clone());
|
let mut builder = MastodonBuilder::new();
|
||||||
builder.client(self.client.clone()).data(data);
|
builder.client(self.client.clone()).data(data);
|
||||||
Ok(builder.build()?)
|
Ok(builder.build()?)
|
||||||
}
|
}
|
||||||
@@ -350,7 +335,7 @@ impl<H: HttpSend> Registered<H> {
|
|||||||
/// Represents the state of the auth flow when the app has been registered but
|
/// Represents the state of the auth flow when the app has been registered but
|
||||||
/// the user is not authenticated
|
/// the user is not authenticated
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Registered<H: HttpSend> {
|
pub struct Registered {
|
||||||
base: String,
|
base: String,
|
||||||
client: Client,
|
client: Client,
|
||||||
client_id: String,
|
client_id: String,
|
||||||
@@ -358,7 +343,6 @@ pub struct Registered<H: HttpSend> {
|
|||||||
redirect: String,
|
redirect: String,
|
||||||
scopes: Scopes,
|
scopes: Scopes,
|
||||||
force_login: bool,
|
force_login: bool,
|
||||||
http_sender: H,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -370,15 +354,13 @@ mod tests {
|
|||||||
let r = Registration::new("https://example.com");
|
let r = Registration::new("https://example.com");
|
||||||
assert_eq!(r.base, "https://example.com".to_string());
|
assert_eq!(r.base, "https://example.com".to_string());
|
||||||
assert_eq!(r.app_builder, AppBuilder::new());
|
assert_eq!(r.app_builder, AppBuilder::new());
|
||||||
assert_eq!(r.http_sender, HttpSender);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_registration_with_sender() {
|
fn test_registration_with_sender() {
|
||||||
let r = Registration::with_sender("https://example.com", HttpSender);
|
let r = Registration::new("https://example.com");
|
||||||
assert_eq!(r.base, "https://example.com".to_string());
|
assert_eq!(r.base, "https://example.com".to_string());
|
||||||
assert_eq!(r.app_builder, AppBuilder::new());
|
assert_eq!(r.app_builder, AppBuilder::new());
|
||||||
assert_eq!(r.http_sender, HttpSender);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::time::Duration;
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::{entities::filter::FilterContext, requests::AddFilterRequest};
|
/// use elefren::{entities::filter::FilterContext, requests::AddFilterRequest};
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let request = AddFilterRequest::new("foo", FilterContext::Home);
|
/// let request = AddFilterRequest::new("foo", FilterContext::Home);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
|
|||||||
+7
-7
@@ -90,7 +90,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::Scopes;
|
/// use elefren::scopes::Scopes;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::all();
|
/// let scope = Scopes::all();
|
||||||
/// assert_eq!(&format!("{}", scope), "read write follow push");
|
/// assert_eq!(&format!("{}", scope), "read write follow push");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -107,7 +107,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::Scopes;
|
/// use elefren::scopes::Scopes;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::read_all();
|
/// let scope = Scopes::read_all();
|
||||||
/// assert_eq!(&format!("{}", scope), "read");
|
/// assert_eq!(&format!("{}", scope), "read");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -124,7 +124,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::{Read, Scopes};
|
/// use elefren::scopes::{Read, Scopes};
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::read(Read::Accounts);
|
/// let scope = Scopes::read(Read::Accounts);
|
||||||
/// assert_eq!(&format!("{}", scope), "read:accounts");
|
/// assert_eq!(&format!("{}", scope), "read:accounts");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -141,7 +141,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::Scopes;
|
/// use elefren::scopes::Scopes;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::write_all();
|
/// let scope = Scopes::write_all();
|
||||||
/// assert_eq!(&format!("{}", scope), "write");
|
/// assert_eq!(&format!("{}", scope), "write");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -158,7 +158,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::{Scopes, Write};
|
/// use elefren::scopes::{Scopes, Write};
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::write(Write::Accounts);
|
/// let scope = Scopes::write(Write::Accounts);
|
||||||
/// assert_eq!(&format!("{}", scope), "write:accounts");
|
/// assert_eq!(&format!("{}", scope), "write:accounts");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -175,7 +175,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::Scopes;
|
/// use elefren::scopes::Scopes;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::follow();
|
/// let scope = Scopes::follow();
|
||||||
/// assert_eq!(&format!("{}", scope), "follow");
|
/// assert_eq!(&format!("{}", scope), "follow");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@@ -192,7 +192,7 @@ impl Scopes {
|
|||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
/// use elefren::scopes::Scopes;
|
/// use elefren::scopes::Scopes;
|
||||||
///
|
///
|
||||||
/// # fn main() -> Result<(), Box<Error>> {
|
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||||
/// let scope = Scopes::push();
|
/// let scope = Scopes::push();
|
||||||
/// assert_eq!(&format!("{}", scope), "push");
|
/// assert_eq!(&format!("{}", scope), "push");
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user