Update Rust Edition; Update dependencies
Async needs added
This commit is contained in:
parent
96b16c62d9
commit
f054c7d805
|
@ -2,4 +2,4 @@ export TOKEN='snakeoil'
|
|||
export CLIENT_ID=''
|
||||
export CLIENT_SECRET=''
|
||||
export REDIRECT=''
|
||||
export BASE='https://mastodon.social'
|
||||
export BASE='https://botsin.space'
|
||||
|
|
|
@ -52,10 +52,10 @@ This release adds support for all new API endpoints introduced in Mastodon 2.4.*
|
|||
* **scopes:** Implement granular OAuth scopes ([e284894d](e284894d), closes [#44](44))
|
||||
* **helpers:** cli::authenticate ([034bd4e6](034bd4e6))
|
||||
* **client:** Implement client.update\_credentials ([a57c7e2f](a57c7e2f))
|
||||
* **status:** Add language code to status builer ([989d9a59](989d9a59), closes [#55](55))
|
||||
* **status:** Add language code to status builder ([989d9a59](989d9a59), closes [#55](55))
|
||||
* **client:** Implement profile metadata update ([0ad1e374](0ad1e374), closes [#54](54))
|
||||
* **search:** Implement `GET /api/v2/search` ([28192e11](28192e11))
|
||||
* **client:** Implement push notifciations endpoints ([690b029d](690b029d), closes [#53](53))
|
||||
* **client:** Implement push notifications endpoints ([690b029d](690b029d), closes [#53](53))
|
||||
* **client:** Add `replies_count` property to `Status` entities ([7d752a9f](7d752a9f), closes [#73](73))
|
||||
* **client:** Implement Keyword filtering API ([7d164cb8](7d164cb8), closes [#71](71))
|
||||
* **client:** Implement the Follow Suggestions API ([7de1bdc0](7de1bdc0), closes [#72](72))
|
||||
|
@ -111,7 +111,7 @@ This release adds support for all new API endpoints introduced in Mastodon 2.4.*
|
|||
```
|
||||
|
||||
You can still call use the `Registration` & `AppBuilder` APIs like
|
||||
before, but any App passed to `.register` will supercede anything app
|
||||
before, but any App passed to `.register` will supersede anything app
|
||||
config set on the `Registration` object itself.
|
||||
|
||||
In future releases, this will become a hard error.
|
||||
|
|
33
Cargo.toml
33
Cargo.toml
|
@ -12,14 +12,17 @@
|
|||
|
||||
[package]
|
||||
name = "elefren"
|
||||
version = "0.22.0"
|
||||
version = "0.23.0"
|
||||
authors = ["Aaron Power <theaaronepower@gmail.com>", "Paul Woolcock <paul@woolcock.us>"]
|
||||
description = "A wrapper around the Mastodon API."
|
||||
readme = "README.md"
|
||||
keywords = ["api", "web", "social", "mastodon", "wrapper"]
|
||||
categories = ["web-programming", "web-programming::http-client", "api-bindings"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/pwoolcoc/elefren.git"
|
||||
edition = "2021"
|
||||
# TODO setup repo
|
||||
# repository = "https://github.com/pwoolcoc/elefren.git"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["all"]
|
||||
[dependencies.chrono]
|
||||
|
@ -30,15 +33,16 @@ features = ["serde"]
|
|||
version = "0.3"
|
||||
|
||||
[dependencies.envy]
|
||||
version = "0.4.0"
|
||||
version = "0.4"
|
||||
optional = true
|
||||
|
||||
# Provides parsing for the link header in get_links() in page.rs
|
||||
[dependencies.hyper-old-types]
|
||||
version = "0.11.0"
|
||||
|
||||
[dependencies.isolang]
|
||||
version = "1.0"
|
||||
features = ["serde_serialize"]
|
||||
version = "2.2"
|
||||
features = ["serde"]
|
||||
|
||||
[dependencies.log]
|
||||
version = "0.4"
|
||||
|
@ -49,9 +53,7 @@ default-features = false
|
|||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
|
||||
[dependencies.serde_derive]
|
||||
version = "1"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1"
|
||||
|
@ -66,30 +68,29 @@ version = "0.6.1"
|
|||
version = "1"
|
||||
|
||||
[dependencies.toml]
|
||||
version = "0.5.0"
|
||||
version = "0.5"
|
||||
optional = true
|
||||
|
||||
[dependencies.try_from]
|
||||
version = "0.3.2"
|
||||
|
||||
[dependencies.tungstenite]
|
||||
version = "0.10.1"
|
||||
|
||||
[dependencies.url]
|
||||
version = "1"
|
||||
|
||||
[dev-dependencies.indoc]
|
||||
version = "0.3.1"
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.pretty_env_logger]
|
||||
version = "0.3.0"
|
||||
|
||||
[dev-dependencies.skeptic]
|
||||
version = "0.13.3"
|
||||
version = "0.13"
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
version = "3.0.3"
|
||||
version = "3"
|
||||
|
||||
[build-dependencies.skeptic]
|
||||
version = "0.13.3"
|
||||
version = "0.13"
|
||||
|
||||
[features]
|
||||
all = ["toml", "json", "env"]
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
[Documentation](https://docs.rs/elefren/)
|
||||
|
||||
A wrapper around the [API](https://github.com/tootsuite/documentation/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://botsin.space/)
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -33,7 +33,6 @@ elefren = { version = "0.22", features = ["toml"] }
|
|||
|
||||
```rust,no_run
|
||||
// src/main.rs
|
||||
extern crate elefren;
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
|
@ -56,7 +55,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
|
||||
fn register() -> Result<Mastodon, Box<dyn Error>> {
|
||||
let registration = Registration::new("https://mastodon.social")
|
||||
let registration = Registration::new("https://botsin.space")
|
||||
.client_name("elefren-examples")
|
||||
.build()?;
|
||||
let mastodon = cli::authenticate(registration)?;
|
||||
|
@ -70,7 +69,7 @@ fn register() -> Result<Mastodon, Box<dyn Error>> {
|
|||
|
||||
It also supports the [Streaming API](https://docs.joinmastodon.org/api/streaming):
|
||||
|
||||
```no_run
|
||||
```rust,no_run
|
||||
use elefren::prelude::*;
|
||||
use elefren::entities::event::Event;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#![cfg_attr(not(feature = "toml"), allow(unused_imports))]
|
||||
#[macro_use]
|
||||
extern crate pretty_env_logger;
|
||||
extern crate elefren;
|
||||
mod register;
|
||||
|
||||
use register::MastodonClient;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#![cfg_attr(not(feature = "toml"), allow(unused_imports))]
|
||||
#[macro_use]
|
||||
extern crate pretty_env_logger;
|
||||
extern crate elefren;
|
||||
mod register;
|
||||
|
||||
use register::MastodonClient;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#![cfg_attr(not(feature = "toml"), allow(unused_imports))]
|
||||
#[macro_use]
|
||||
extern crate pretty_env_logger;
|
||||
extern crate elefren;
|
||||
mod register;
|
||||
|
||||
use register::MastodonClient;
|
||||
|
|
39
src/apps.rs
39
src/apps.rs
|
@ -1,9 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use try_from::TryInto;
|
||||
use serde::Serialize;
|
||||
// use try_from::TryInto;
|
||||
|
||||
use errors::{Error, Result};
|
||||
use scopes::Scopes;
|
||||
use crate::{
|
||||
errors::{Error, Result},
|
||||
scopes::Scopes,
|
||||
};
|
||||
|
||||
/// Represents an application that can be registered with a mastodon instance
|
||||
#[derive(Clone, Debug, Default, Serialize, PartialEq)]
|
||||
|
@ -18,10 +21,9 @@ pub struct App {
|
|||
impl App {
|
||||
/// Get an AppBuilder object
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::apps::App;
|
||||
///
|
||||
/// let mut builder = App::builder();
|
||||
|
@ -32,21 +34,16 @@ impl App {
|
|||
|
||||
/// Retrieve the list of scopes that apply to this App
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::Error;
|
||||
/// use elefren::{apps::App, scopes::Scopes};
|
||||
///
|
||||
/// # fn main() -> Result<(), Error> {
|
||||
/// let mut builder = App::builder();
|
||||
/// builder.client_name("elefren-test");
|
||||
/// let app = builder.build()?;
|
||||
/// let app = builder.build().unwrap();
|
||||
/// let scopes = app.scopes();
|
||||
/// assert_eq!(scopes, &Scopes::read_all());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn scopes(&self) -> &Scopes {
|
||||
&self.scopes
|
||||
|
@ -55,15 +52,11 @@ impl App {
|
|||
|
||||
/// Builder struct for defining your application.
|
||||
/// ```
|
||||
/// use elefren::apps::App;
|
||||
/// use std::error::Error;
|
||||
/// use elefren::{apps::App};
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let mut builder = App::builder();
|
||||
/// builder.client_name("elefren_test");
|
||||
/// let app = builder.build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// let app = builder.build().unwrap();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
|
||||
pub struct AppBuilder<'a> {
|
||||
|
@ -129,16 +122,8 @@ impl<'a> AppBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryInto<App> for App {
|
||||
type Err = Error;
|
||||
|
||||
fn try_into(self) -> Result<App> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryInto<App> for AppBuilder<'a> {
|
||||
type Err = Error;
|
||||
type Error = Error;
|
||||
|
||||
fn try_into(self) -> Result<App> {
|
||||
Ok(self.build()?)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Raw data about mastodon app. Save `Data` using `serde` to prevent needing
|
||||
/// to authenticate on every run.
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)]
|
||||
pub struct Data {
|
||||
/// Base url of instance eg. `https://mastodon.social`.
|
||||
/// Base url of instance eg. `https://botsin.space`.
|
||||
pub base: Cow<'static, str>,
|
||||
/// The client's id given by the instance.
|
||||
pub client_id: Cow<'static, str>,
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
//! A module containing everything relating to a account returned from the api.
|
||||
|
||||
use crate::status_builder;
|
||||
use chrono::prelude::*;
|
||||
use serde::de::{self, Deserialize, Deserializer, Unexpected};
|
||||
use status_builder;
|
||||
use serde::{
|
||||
de::{self, Deserializer, Unexpected},
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A struct representing an Account.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! Module containing everything related to media attachements.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A struct representing a media attachment.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
pub struct Attachment {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! Module representing cards of statuses.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A card of a status.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
pub struct Card {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! A module about contexts of statuses.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::status::Status;
|
||||
|
||||
/// A context of a status returning a list of statuses it replied to and
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use entities::{notification::Notification, status::Status};
|
||||
use crate::entities::{notification::Notification, status::Status};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// Events that come from the /streaming/user API call
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Represents a single Filter
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Filter {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
//! Module containing everything related to an instance.
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::account::Account;
|
||||
|
||||
/// A struct containing info of an instance.
|
||||
|
|
|
@ -1,28 +1,16 @@
|
|||
use http_send::HttpSend;
|
||||
use page::Page;
|
||||
use crate::{http_send::HttpSend, page::Page};
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Abstracts away the `next_page` logic into a single stream of items
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use std::error::Error;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::prelude::*;
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let statuses = client.statuses("user-id", None)?;
|
||||
/// let statuses = client.statuses("user-id", None).unwrap();
|
||||
/// for status in statuses.items_iter() {
|
||||
/// // do something with `status`
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct ItemsIter<'a, T: Clone + for<'de> Deserialize<'de>, H: 'a + HttpSend> {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
/// Used for ser/de of list resources
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
pub struct List {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
/// Data structures for ser/de of account-related resources
|
||||
pub mod account;
|
||||
/// Data structures for ser/de of attachment-related resources
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use super::{account::Account, status::Status};
|
||||
use chrono::prelude::*;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A struct containing info about a notification.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Represents the `alerts` key of the `Subscription` object
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
|
||||
pub struct Alerts {
|
||||
|
@ -25,6 +27,8 @@ pub struct Subscription {
|
|||
}
|
||||
|
||||
pub(crate) mod add_subscription {
|
||||
use serde::Serialize;
|
||||
|
||||
use super::Alerts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Default)]
|
||||
|
@ -52,6 +56,8 @@ pub(crate) mod add_subscription {
|
|||
}
|
||||
|
||||
pub(crate) mod update_data {
|
||||
use serde::Serialize;
|
||||
|
||||
use super::Alerts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Default)]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! module containing everything relating to a relationship with
|
||||
//! another account.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A struct containing information about a relationship with another account.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
pub struct Relationship {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! module containing information about a finished report of a user.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A struct containing info about a report.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
pub struct Report {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! A module containing info relating to a search result.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{
|
||||
prelude::{Account, Status},
|
||||
status::Tag,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Module containing all info relating to a status.
|
||||
|
||||
use super::prelude::*;
|
||||
use crate::{entities::card::Card, status_builder::Visibility};
|
||||
use chrono::prelude::*;
|
||||
use entities::card::Card;
|
||||
use status_builder::Visibility;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// A status from the instance.
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::{error, fmt, io::Error as IoError};
|
|||
use envy::Error as EnvyError;
|
||||
use hyper_old_types::Error as HeaderParseError;
|
||||
use reqwest::{header::ToStrError as HeaderStrError, Error as HttpError, StatusCode};
|
||||
use serde::Deserialize;
|
||||
use serde_json::Error as SerdeError;
|
||||
use serde_qs::Error as SerdeQsError;
|
||||
use serde_urlencoded::ser::Error as UrlEncodedError;
|
||||
|
@ -11,8 +12,8 @@ use serde_urlencoded::ser::Error as UrlEncodedError;
|
|||
use tomlcrate::de::Error as TomlDeError;
|
||||
#[cfg(feature = "toml")]
|
||||
use tomlcrate::ser::Error as TomlSerError;
|
||||
use url::ParseError as UrlError;
|
||||
use tungstenite::error::Error as WebSocketError;
|
||||
use url::ParseError as UrlError;
|
||||
|
||||
/// Convience type over `std::result::Result` with `Error` as the error type.
|
||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||
|
@ -93,9 +94,7 @@ impl error::Error for Error {
|
|||
Error::SerdeQs(ref e) => e,
|
||||
Error::WebSocket(ref e) => e,
|
||||
|
||||
Error::Client(..) | Error::Server(..) => {
|
||||
return None
|
||||
},
|
||||
Error::Client(..) | Error::Server(..) => return None,
|
||||
Error::ClientIdRequired => return None,
|
||||
Error::ClientSecretRequired => return None,
|
||||
Error::AccessTokenRequired => return None,
|
||||
|
@ -167,9 +166,6 @@ macro_rules! format_err {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use reqwest;
|
||||
use serde_json;
|
||||
use serde_urlencoded;
|
||||
use std::io;
|
||||
|
||||
macro_rules! assert_is {
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{self, BufRead, Write};
|
||||
|
||||
use errors::Result;
|
||||
use http_send::HttpSend;
|
||||
use registration::Registered;
|
||||
use Mastodon;
|
||||
use crate::{errors::Result, http_send::HttpSend, registration::Registered, Mastodon};
|
||||
|
||||
/// Finishes the authentication process for the given `Registered` object,
|
||||
/// using the command-line
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use envy;
|
||||
|
||||
use crate::Result;
|
||||
use data::Data;
|
||||
use Result;
|
||||
|
||||
/// Attempts to deserialize a Data struct from the environment
|
||||
pub fn from_env() -> Result<Data> {
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::{
|
|||
|
||||
use serde_json;
|
||||
|
||||
use crate::Result;
|
||||
use data::Data;
|
||||
use Result;
|
||||
|
||||
/// Attempts to deserialize a Data struct from a string
|
||||
pub fn from_str(s: &str) -> Result<Data> {
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::{
|
|||
|
||||
use tomlcrate;
|
||||
|
||||
use crate::Result;
|
||||
use data::Data;
|
||||
use Result;
|
||||
|
||||
/// Attempts to deserialize a Data struct from a string
|
||||
pub fn from_str(s: &str) -> Result<Data> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Result;
|
||||
use reqwest::{Client, Request, RequestBuilder, Response};
|
||||
use std::fmt::Debug;
|
||||
use Result;
|
||||
|
||||
/// Abstracts away the process of turning an HTTP request into an HTTP response
|
||||
pub trait HttpSend: Clone + Debug {
|
||||
|
|
116
src/lib.rs
116
src/lib.rs
|
@ -1,51 +1,36 @@
|
|||
//! # Elefren: API Wrapper around the Mastodon API.
|
||||
//! // Elefren: API Wrapper around the Mastodon API.
|
||||
//!
|
||||
//! Most of the api is documented on [Mastodon's website](https://docs.joinmastodon.org/client/intro/)
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # extern crate elefren;
|
||||
//! # fn main() {
|
||||
//! # try().unwrap();
|
||||
//! # }
|
||||
//! # fn try() -> elefren::Result<()> {
|
||||
//! use elefren::{helpers::cli, prelude::*};
|
||||
//!
|
||||
//! let registration = Registration::new("https://mastodon.social")
|
||||
//! let registration = Registration::new("https://botsin.space")
|
||||
//! .client_name("elefren_test")
|
||||
//! .build()?;
|
||||
//! let mastodon = cli::authenticate(registration)?;
|
||||
//! .build()
|
||||
//! .unwrap();
|
||||
//! let mastodon = cli::authenticate(registration).unwrap();
|
||||
//!
|
||||
//! println!(
|
||||
//! "{:?}",
|
||||
//! mastodon
|
||||
//! .get_home_timeline()?
|
||||
//! .get_home_timeline()
|
||||
//! .unwrap()
|
||||
//! .items_iter()
|
||||
//! .take(100)
|
||||
//! .collect::<Vec<_>>()
|
||||
//! );
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Elefren also supports Mastodon's Streaming API:
|
||||
//!
|
||||
//! # Example
|
||||
//! // Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # extern crate elefren;
|
||||
//! # use elefren::prelude::*;
|
||||
//! # use std::error::Error;
|
||||
//! use elefren::entities::event::Event;
|
||||
//! # fn main() -> Result<(), Box<Error>> {
|
||||
//! # let data = Data {
|
||||
//! # base: "".into(),
|
||||
//! # client_id: "".into(),
|
||||
//! # client_secret: "".into(),
|
||||
//! # redirect: "".into(),
|
||||
//! # token: "".into(),
|
||||
//! # };
|
||||
//! use elefren::{prelude::*, entities::event::Event};
|
||||
//! let data = Data::default();
|
||||
//! let client = Mastodon::from(data);
|
||||
//! for event in client.streaming_user()? {
|
||||
//! for event in client.streaming_user().unwrap() {
|
||||
//! match event {
|
||||
//! Event::Update(ref status) => { /* .. */ },
|
||||
//! Event::Notification(ref notification) => { /* .. */ },
|
||||
|
@ -53,8 +38,6 @@
|
|||
//! Event::FiltersChanged => { /* .. */ },
|
||||
//! }
|
||||
//! }
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![deny(
|
||||
|
@ -73,8 +56,6 @@
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate doc_comment;
|
||||
extern crate hyper_old_types;
|
||||
extern crate isolang;
|
||||
|
@ -82,11 +63,11 @@ extern crate isolang;
|
|||
extern crate serde_json;
|
||||
extern crate chrono;
|
||||
extern crate reqwest;
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
extern crate serde_qs;
|
||||
extern crate serde_urlencoded;
|
||||
extern crate tap_reader;
|
||||
extern crate try_from;
|
||||
extern crate tungstenite;
|
||||
extern crate url;
|
||||
|
||||
|
@ -154,14 +135,16 @@ pub mod status_builder;
|
|||
mod macros;
|
||||
/// Automatically import the things you need
|
||||
pub mod prelude {
|
||||
pub use scopes::Scopes;
|
||||
pub use Data;
|
||||
pub use Mastodon;
|
||||
pub use MastodonClient;
|
||||
pub use NewStatus;
|
||||
pub use Registration;
|
||||
pub use StatusBuilder;
|
||||
pub use StatusesRequest;
|
||||
pub use crate::{
|
||||
scopes::Scopes,
|
||||
Data,
|
||||
Mastodon,
|
||||
MastodonClient,
|
||||
NewStatus,
|
||||
Registration,
|
||||
StatusBuilder,
|
||||
StatusesRequest,
|
||||
};
|
||||
}
|
||||
|
||||
/// Your mastodon application client, handles all requests to and from Mastodon.
|
||||
|
@ -344,44 +327,22 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||
/// Get statuses of a single account by id. Optionally only with pictures
|
||||
/// and or excluding replies.
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use std::error::Error;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::prelude::*;
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let statuses = client.statuses("user-id", None)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// let statuses = client.statuses("user-id", None).unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use std::error::Error;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::prelude::*;
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// request.only_media();
|
||||
/// let statuses = client.statuses("user-id", request)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// let statuses = client.statuses("user-id", request).unwrap();
|
||||
/// ```
|
||||
fn statuses<'a, 'b: 'a, S>(&'b self, id: &'b str, request: S) -> Result<Page<Status, H>>
|
||||
where
|
||||
|
@ -460,23 +421,14 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||
/// returns events that are relevant to the authorized user, i.e. home
|
||||
/// timeline & notifications
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::prelude::*;
|
||||
/// use elefren::entities::event::Event;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// for event in client.streaming_user()? {
|
||||
/// for event in client.streaming_user().unwrap() {
|
||||
/// match event {
|
||||
/// Event::Update(ref status) => { /* .. */ },
|
||||
/// Event::Notification(ref notification) => { /* .. */ },
|
||||
|
@ -484,8 +436,6 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||
/// Event::FiltersChanged => { /* .. */ },
|
||||
/// }
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn streaming_user(&self) -> Result<Self::Stream> {
|
||||
let mut url: url::Url = self.route("/api/v1/streaming").parse()?;
|
||||
|
|
|
@ -24,20 +24,10 @@ macro_rules! paged_routes {
|
|||
"`\n# Errors\nIf `access_token` is not set.",
|
||||
"\n",
|
||||
"```no_run",
|
||||
"# extern crate elefren;\n",
|
||||
"# use elefren::prelude::*;\n",
|
||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
||||
"# let data = Data {\n",
|
||||
"# base: \"https://example.com\".into(),\n",
|
||||
"# client_id: \"taosuah\".into(),\n",
|
||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
||||
"# redirect: \"https://example.com\".into(),\n",
|
||||
"# token: \"tsaohueaheis\".into(),\n",
|
||||
"# };\n",
|
||||
"use elefren::prelude::*;\n",
|
||||
"let data = Data::default();\n",
|
||||
"let client = Mastodon::from(data);\n",
|
||||
"client.", stringify!($name), "();\n",
|
||||
"# Ok(())\n",
|
||||
"# }\n",
|
||||
"```"
|
||||
),
|
||||
fn $name(&self) -> Result<Page<$ret, H>> {
|
||||
|
@ -259,20 +249,10 @@ macro_rules! route {
|
|||
"`\n# Errors\nIf `access_token` is not set.",
|
||||
"\n",
|
||||
"```no_run",
|
||||
"# extern crate elefren;\n",
|
||||
"# use elefren::prelude::*;\n",
|
||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
||||
"# let data = Data {\n",
|
||||
"# base: \"https://example.com\".into(),\n",
|
||||
"# client_id: \"taosuah\".into(),\n",
|
||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
||||
"# redirect: \"https://example.com\".into(),\n",
|
||||
"# token: \"tsaohueaheis\".into(),\n",
|
||||
"# };\n",
|
||||
"use elefren::prelude::*;\n",
|
||||
"let data = Data::default();\n",
|
||||
"let client = Mastodon::from(data);\n",
|
||||
"client.", stringify!($name), "();\n",
|
||||
"# Ok(())\n",
|
||||
"# }\n",
|
||||
"```"
|
||||
),
|
||||
fn $name(&self) -> Result<$ret> {
|
||||
|
@ -297,16 +277,8 @@ macro_rules! route_id {
|
|||
"`\n# Errors\nIf `access_token` is not set.",
|
||||
"\n",
|
||||
"```no_run",
|
||||
"# extern crate elefren;\n",
|
||||
"# use elefren::prelude::*;\n",
|
||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
||||
"# let data = Data {\n",
|
||||
"# base: \"https://example.com\".into(),\n",
|
||||
"# client_id: \"taosuah\".into(),\n",
|
||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
||||
"# redirect: \"https://example.com\".into(),\n",
|
||||
"# token: \"tsaohueaheis\".into(),\n",
|
||||
"# };\n",
|
||||
"use elefren::prelude::*;\n",
|
||||
"let data = Data::default();\n",
|
||||
"let client = Mastodon::from(data);\n",
|
||||
"client.", stringify!($name), "(\"42\");\n",
|
||||
"# Ok(())\n",
|
||||
|
@ -331,20 +303,10 @@ macro_rules! paged_routes_with_id {
|
|||
"`\n# Errors\nIf `access_token` is not set.",
|
||||
"\n",
|
||||
"```no_run",
|
||||
"# extern crate elefren;\n",
|
||||
"# use elefren::prelude::*;\n",
|
||||
"# fn main() -> Result<(), Box<::std::error::Error>> {\n",
|
||||
"# let data = Data {\n",
|
||||
"# base: \"https://example.com\".into(),\n",
|
||||
"# client_id: \"taosuah\".into(),\n",
|
||||
"# client_secret: \"htnjdiuae\".into(),\n",
|
||||
"# redirect: \"https://example.com\".into(),\n",
|
||||
"# token: \"tsaohueaheis\".into(),\n",
|
||||
"# };\n",
|
||||
"use elefren::prelude::*;\n",
|
||||
"let data = Data::default();",
|
||||
"let client = Mastodon::from(data);\n",
|
||||
"client.", stringify!($name), "(\"some-id\");\n",
|
||||
"# Ok(())\n",
|
||||
"# }\n",
|
||||
"```"
|
||||
),
|
||||
fn $name(&self, id: &str) -> Result<Page<$ret, H>> {
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use entities::prelude::*;
|
||||
use errors::Result;
|
||||
use http_send::{HttpSend, HttpSender};
|
||||
use page::Page;
|
||||
use requests::{
|
||||
use crate::{
|
||||
entities::prelude::*,
|
||||
errors::Result,
|
||||
http_send::{HttpSend, HttpSender},
|
||||
page::Page,
|
||||
requests::{
|
||||
AddFilterRequest,
|
||||
AddPushRequest,
|
||||
StatusesRequest,
|
||||
UpdateCredsRequest,
|
||||
UpdatePushRequest,
|
||||
},
|
||||
status_builder::NewStatus,
|
||||
};
|
||||
use status_builder::NewStatus;
|
||||
|
||||
/// Represents the set of methods that a Mastodon Client can do, so that
|
||||
/// implementations might be swapped out for testing
|
||||
|
@ -283,21 +285,11 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||
/// Shortcut for: `let me = client.verify_credentials(); client.followers()`
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// # let client = Mastodon::from(data);
|
||||
/// let follows_me = client.follows_me()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// use elefren::prelude::*;
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let follows_me = client.follows_me().unwrap();
|
||||
/// ```
|
||||
fn follows_me(&self) -> Result<Page<Account, H>> {
|
||||
unimplemented!("This method was not implemented");
|
||||
}
|
||||
|
@ -305,21 +297,11 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||
/// `let me = client.verify_credentials(); client.following(&me.id)`
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// # let client = Mastodon::from(data);
|
||||
/// let follows_me = client.followed_by_me()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// use elefren::prelude::*;
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let follows_me = client.followed_by_me().unwrap();
|
||||
/// ```
|
||||
fn followed_by_me(&self) -> Result<Page<Account, H>> {
|
||||
unimplemented!("This method was not implemented");
|
||||
}
|
||||
|
|
75
src/page.rs
75
src/page.rs
|
@ -1,11 +1,11 @@
|
|||
use super::{deserialise, Mastodon, Result};
|
||||
use entities::itemsiter::ItemsIter;
|
||||
use crate::entities::itemsiter::ItemsIter;
|
||||
use hyper_old_types::header::{parsing, Link, RelationType};
|
||||
use reqwest::{header::LINK, Response};
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
use http_send::HttpSend;
|
||||
use crate::http_send::HttpSend;
|
||||
|
||||
macro_rules! pages {
|
||||
($($direction:ident: $fun:ident),*) => {
|
||||
|
@ -36,36 +36,28 @@ macro_rules! pages {
|
|||
/// Owned version of the `Page` struct in this module. Allows this to be more
|
||||
/// easily stored for later use
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::Mastodon;
|
||||
/// # use elefren::page::OwnedPage;
|
||||
/// # use elefren::http_send::HttpSender;
|
||||
/// # use elefren::entities::status::Status;
|
||||
/// # use std::cell::RefCell;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::{
|
||||
/// prelude::*,
|
||||
/// page::OwnedPage,
|
||||
/// http_send::HttpSender,
|
||||
/// entities::status::Status
|
||||
/// };
|
||||
/// use std::cell::RefCell;
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// struct HomeTimeline {
|
||||
/// client: Mastodon,
|
||||
/// page: RefCell<Option<OwnedPage<Status, HttpSender>>>,
|
||||
/// }
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let home = client.get_home_timeline()?.to_owned();
|
||||
/// let home = client.get_home_timeline().unwrap().to_owned();
|
||||
/// let tl = HomeTimeline {
|
||||
/// client,
|
||||
/// page: RefCell::new(Some(home)),
|
||||
/// };
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OwnedPage<T: for<'de> Deserialize<'de>, H: HttpSend> {
|
||||
|
@ -125,36 +117,22 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||
/// Returns an owned version of this struct that doesn't borrow the client
|
||||
/// that created it
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::Mastodon;
|
||||
/// # use elefren::page::OwnedPage;
|
||||
/// # use elefren::http_send::HttpSender;
|
||||
/// # use elefren::entities::status::Status;
|
||||
/// # use std::cell::RefCell;
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::{Mastodon, page::OwnedPage, http_send::HttpSender, entities::status::Status, prelude::*};
|
||||
/// use std::cell::RefCell;
|
||||
/// let data = Data::default();
|
||||
/// struct HomeTimeline {
|
||||
/// client: Mastodon,
|
||||
/// page: RefCell<Option<OwnedPage<Status, HttpSender>>>,
|
||||
/// }
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let home = client.get_home_timeline()?.to_owned();
|
||||
/// let home = client.get_home_timeline().unwrap().to_owned();
|
||||
/// let tl = HomeTimeline {
|
||||
/// client,
|
||||
/// page: RefCell::new(Some(home)),
|
||||
/// };
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_owned(self) -> OwnedPage<T, H> {
|
||||
OwnedPage::from(self)
|
||||
|
@ -170,28 +148,17 @@ impl<'a, T: Clone + for<'de> Deserialize<'de>, H: HttpSend> Page<'a, T, H> {
|
|||
/// more of them, until
|
||||
/// there are no more items.
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// let data = Data::default();
|
||||
/// let mastodon = Mastodon::from(data);
|
||||
/// let req = StatusesRequest::new();
|
||||
/// let resp = mastodon.statuses("some-id", req)?;
|
||||
/// let resp = mastodon.statuses("some-id", req).unwrap();
|
||||
/// for status in resp.items_iter() {
|
||||
/// // do something with status
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn items_iter(self) -> impl Iterator<Item = T> + 'a
|
||||
where
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use reqwest::{Client, RequestBuilder, Response};
|
||||
use try_from::TryInto;
|
||||
use url::percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
|
||||
|
||||
use apps::{App, AppBuilder};
|
||||
use http_send::{HttpSend, HttpSender};
|
||||
use scopes::Scopes;
|
||||
use Data;
|
||||
use Error;
|
||||
use Mastodon;
|
||||
use MastodonBuilder;
|
||||
use Result;
|
||||
use crate::{
|
||||
apps::{App, AppBuilder},
|
||||
http_send::{HttpSend, HttpSender},
|
||||
scopes::Scopes,
|
||||
Data,
|
||||
Error,
|
||||
Mastodon,
|
||||
MastodonBuilder,
|
||||
Result,
|
||||
};
|
||||
|
||||
const DEFAULT_REDIRECT_URI: &'static str = "urn:ietf:wg:oauth:2.0:oob";
|
||||
|
||||
|
@ -48,7 +49,7 @@ impl<'a> Registration<'a, HttpSender> {
|
|||
/// ```
|
||||
/// use elefren::prelude::*;
|
||||
///
|
||||
/// let registration = Registration::new("https://mastodon.social");
|
||||
/// let registration = Registration::new("https://botsin.space");
|
||||
/// ```
|
||||
pub fn new<I: Into<String>>(base: I) -> Self {
|
||||
Registration {
|
||||
|
@ -116,27 +117,23 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||
/// Register the given application
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # fn main () -> elefren::Result<()> {
|
||||
/// use elefren::{apps::App, prelude::*};
|
||||
///
|
||||
/// let mut app = App::builder();
|
||||
/// app.client_name("elefren_test");
|
||||
///
|
||||
/// let registration = Registration::new("https://mastodon.social").register(app)?;
|
||||
/// let url = registration.authorize_url()?;
|
||||
/// let registration = Registration::new("https://botsin.space").register(app).unwrap();
|
||||
/// let url = registration.authorize_url().unwrap();
|
||||
/// // Here you now need to open the url in the browser
|
||||
/// // And handle a the redirect url coming back with the code.
|
||||
/// let code = String::from("RETURNED_FROM_BROWSER");
|
||||
/// let mastodon = registration.complete(&code)?;
|
||||
/// let mastodon = registration.complete(&code).unwrap();
|
||||
///
|
||||
/// println!("{:?}", mastodon.get_home_timeline()?.initial_items);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// println!("{:?}", mastodon.get_home_timeline().unwrap().initial_items);
|
||||
/// ```
|
||||
pub fn register<I: TryInto<App>>(&mut self, app: I) -> Result<Registered<H>>
|
||||
where
|
||||
Error: From<<I as TryInto<App>>::Err>,
|
||||
Error: From<<I as TryInto<App>>::Error>,
|
||||
{
|
||||
let app = app.try_into()?;
|
||||
let oauth = self.send_app(&app)?;
|
||||
|
@ -156,22 +153,18 @@ impl<'a, H: HttpSend> Registration<'a, H> {
|
|||
/// Register the application with the server from the `base` url.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # fn main () -> elefren::Result<()> {
|
||||
/// use elefren::prelude::*;
|
||||
///
|
||||
/// let registration = Registration::new("https://mastodon.social")
|
||||
/// let registration = Registration::new("https://botsin.space")
|
||||
/// .client_name("elefren_test")
|
||||
/// .build()?;
|
||||
/// let url = registration.authorize_url()?;
|
||||
/// .build().unwrap();
|
||||
/// let url = registration.authorize_url().unwrap();
|
||||
/// // Here you now need to open the url in the browser
|
||||
/// // And handle a the redirect url coming back with the code.
|
||||
/// let code = String::from("RETURNED_FROM_BROWSER");
|
||||
/// let mastodon = registration.complete(&code)?;
|
||||
/// let mastodon = registration.complete(&code).unwrap();
|
||||
///
|
||||
/// println!("{:?}", mastodon.get_home_timeline()?.initial_items);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// println!("{:?}", mastodon.get_home_timeline().unwrap().initial_items);
|
||||
/// ```
|
||||
pub fn build(&mut self) -> Result<Registered<H>> {
|
||||
let app: App = self.app_builder.clone().build()?;
|
||||
|
@ -199,11 +192,9 @@ impl Registered<HttpSender> {
|
|||
/// Skip having to retrieve the client id and secret from the server by
|
||||
/// creating a `Registered` struct directly
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # fn main() -> elefren::Result<()> {
|
||||
/// use elefren::{prelude::*, registration::Registered};
|
||||
///
|
||||
/// let registration = Registered::from_parts(
|
||||
|
@ -214,15 +205,13 @@ impl Registered<HttpSender> {
|
|||
/// Scopes::read_all(),
|
||||
/// false,
|
||||
/// );
|
||||
/// let url = registration.authorize_url()?;
|
||||
/// let url = registration.authorize_url().unwrap();
|
||||
/// // Here you now need to open the url in the browser
|
||||
/// // And handle a the redirect url coming back with the code.
|
||||
/// let code = String::from("RETURNED_FROM_BROWSER");
|
||||
/// let mastodon = registration.complete(&code)?;
|
||||
/// let mastodon = registration.complete(&code).unwrap();
|
||||
///
|
||||
/// println!("{:?}", mastodon.get_home_timeline()?.initial_items);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// println!("{:?}", mastodon.get_home_timeline().unwrap().initial_items);
|
||||
/// ```
|
||||
pub fn from_parts(
|
||||
base: &str,
|
||||
|
@ -253,39 +242,35 @@ impl<H: HttpSend> Registered<H> {
|
|||
/// Returns the parts of the `Registered` struct that can be used to
|
||||
/// recreate another `Registered` struct
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::{prelude::*, registration::Registered};
|
||||
/// # fn main() -> Result<(), Box<std::error::Error>> {
|
||||
///
|
||||
/// let origbase = "https://example.social";
|
||||
/// let origclient_id = "some-client_id";
|
||||
/// let origclient_secret = "some-client-secret";
|
||||
/// let origredirect = "https://example.social/redirect";
|
||||
/// let origscopes = Scopes::all();
|
||||
/// let origforce_login = false;
|
||||
/// let orig_base = "https://example.social";
|
||||
/// let orig_client_id = "some-client_id";
|
||||
/// let orig_client_secret = "some-client-secret";
|
||||
/// let orig_redirect = "https://example.social/redirect";
|
||||
/// let orig_scopes = Scopes::all();
|
||||
/// let orig_force_login = false;
|
||||
///
|
||||
/// let registered = Registered::from_parts(
|
||||
/// origbase,
|
||||
/// origclient_id,
|
||||
/// origclient_secret,
|
||||
/// origredirect,
|
||||
/// origscopes.clone(),
|
||||
/// origforce_login,
|
||||
/// orig_base,
|
||||
/// orig_client_id,
|
||||
/// orig_client_secret,
|
||||
/// orig_redirect,
|
||||
/// orig_scopes.clone(),
|
||||
/// orig_force_login,
|
||||
/// );
|
||||
///
|
||||
/// let (base, client_id, client_secret, redirect, scopes, force_login) = registered.into_parts();
|
||||
///
|
||||
/// assert_eq!(origbase, &base);
|
||||
/// assert_eq!(origclient_id, &client_id);
|
||||
/// assert_eq!(origclient_secret, &client_secret);
|
||||
/// assert_eq!(origredirect, &redirect);
|
||||
/// assert_eq!(origscopes, scopes);
|
||||
/// assert_eq!(origforce_login, force_login);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// assert_eq!(orig_base, &base);
|
||||
/// assert_eq!(orig_client_id, &client_id);
|
||||
/// assert_eq!(orig_client_secret, &client_secret);
|
||||
/// assert_eq!(orig_redirect, &redirect);
|
||||
/// assert_eq!(orig_scopes, scopes);
|
||||
/// assert_eq!(orig_force_login, force_login);
|
||||
/// ```
|
||||
pub fn into_parts(self) -> (String, String, String, String, Scopes, bool) {
|
||||
(
|
||||
|
@ -298,7 +283,7 @@ impl<H: HttpSend> Registered<H> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Returns the full url needed for authorisation. This needs to be opened
|
||||
/// Returns the full url needed for authorization. This needs to be opened
|
||||
/// in a browser.
|
||||
pub fn authorize_url(&self) -> Result<String> {
|
||||
let scopes = format!("{}", self.scopes);
|
||||
|
@ -320,7 +305,7 @@ impl<H: HttpSend> Registered<H> {
|
|||
}
|
||||
|
||||
/// Create an access token from the client id, client secret, and code
|
||||
/// provided by the authorisation url.
|
||||
/// provided by the authorization url.
|
||||
pub fn complete(&self, code: &str) -> Result<Mastodon<H>> {
|
||||
let url = format!(
|
||||
"{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&\
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
use entities::filter::FilterContext;
|
||||
use crate::entities::filter::FilterContext;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Form used to create a filter
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::{entities::filter::FilterContext, requests::AddFilterRequest};
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let request = AddFilterRequest::new("foo", FilterContext::Home);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
pub struct AddFilterRequest {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use entities::push::{add_subscription, update_data};
|
||||
use errors::Result;
|
||||
use crate::{
|
||||
entities::push::{add_subscription, update_data},
|
||||
errors::Result,
|
||||
};
|
||||
|
||||
/// Container for the key & auth strings for an AddPushRequest
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::Keys;
|
||||
///
|
||||
/// let keys = Keys::new("anetohias===", "oeatssah=");
|
||||
|
@ -20,10 +21,9 @@ pub struct Keys {
|
|||
impl Keys {
|
||||
/// Create the `Keys` container
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::Keys;
|
||||
///
|
||||
/// let keys = Keys::new("anetohias===", "oeatssah=");
|
||||
|
@ -38,30 +38,20 @@ impl Keys {
|
|||
|
||||
/// Builder to pass to the Mastodon::add_push_subscription method
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::{MastodonClient, Mastodon, Data};
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::{MastodonClient, Mastodon, Data};
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
///
|
||||
/// let keys = Keys::new("stahesuahoei293ise===", "tasecoa,nmeozka==");
|
||||
/// let mut request = AddPushRequest::new("http://example.com/push/endpoint", &keys);
|
||||
/// request.follow().reblog();
|
||||
///
|
||||
/// client.add_push_subscription(&request)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// client.add_push_subscription(&request).unwrap();
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct AddPushRequest {
|
||||
|
@ -79,10 +69,9 @@ pub struct AddPushRequest {
|
|||
impl AddPushRequest {
|
||||
/// Construct a new AddPushRequest
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
/// let keys = Keys::new("abcdef===", "foobar==");
|
||||
/// let push_endpoint = "https://example.com/push/endpoint";
|
||||
|
@ -99,9 +88,8 @@ impl AddPushRequest {
|
|||
|
||||
/// A flag that indicates if you want follow notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
/// let keys = Keys::new("abcdef===", "foobar==");
|
||||
/// let push_endpoint = "https://example.com/push/endpoint";
|
||||
|
@ -115,9 +103,8 @@ impl AddPushRequest {
|
|||
|
||||
/// A flag that indicates if you want favourite notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
/// let keys = Keys::new("abcdef===", "foobar==");
|
||||
/// let push_endpoint = "https://example.com/push/endpoint";
|
||||
|
@ -131,9 +118,8 @@ impl AddPushRequest {
|
|||
|
||||
/// A flag that indicates if you want reblog notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
/// let keys = Keys::new("abcdef===", "foobar==");
|
||||
/// let push_endpoint = "https://example.com/push/endpoint";
|
||||
|
@ -147,9 +133,8 @@ impl AddPushRequest {
|
|||
|
||||
/// A flag that indicates if you want mention notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::{AddPushRequest, Keys};
|
||||
/// let keys = Keys::new("abcdef===", "foobar==");
|
||||
/// let push_endpoint = "https://example.com/push/endpoint";
|
||||
|
@ -169,7 +154,7 @@ impl AddPushRequest {
|
|||
}
|
||||
|
||||
pub(crate) fn build(&self) -> Result<add_subscription::Form> {
|
||||
use entities::push::{
|
||||
use crate::entities::push::{
|
||||
add_subscription::{Data, Form, Keys, Subscription},
|
||||
Alerts,
|
||||
};
|
||||
|
@ -212,29 +197,19 @@ impl AddPushRequest {
|
|||
|
||||
/// Builder to pass to the Mastodon::update_push_data method
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::{MastodonClient, Mastodon, Data};
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// use elefren::{MastodonClient, Mastodon, Data, requests::UpdatePushRequest};
|
||||
/// let data = Data::default();
|
||||
///
|
||||
/// let client = Mastodon::from(data);
|
||||
///
|
||||
/// let mut request = UpdatePushRequest::new("foobar");
|
||||
/// request.follow(true).reblog(true);
|
||||
/// request.follow(true)
|
||||
/// .reblog(true);
|
||||
///
|
||||
/// client.update_push_data(&request)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// client.update_push_data(&request).unwrap();
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
|
||||
pub struct UpdatePushRequest {
|
||||
|
@ -248,12 +223,10 @@ pub struct UpdatePushRequest {
|
|||
impl UpdatePushRequest {
|
||||
/// Construct a new UpdatePushRequest
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// let request = UpdatePushRequest::new("some-id");
|
||||
/// let request = elefren::requests::UpdatePushRequest::new("some-id");
|
||||
/// ```
|
||||
pub fn new(id: &str) -> UpdatePushRequest {
|
||||
UpdatePushRequest {
|
||||
|
@ -264,11 +237,9 @@ impl UpdatePushRequest {
|
|||
|
||||
/// A flag that indicates if you want follow notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// let mut request = UpdatePushRequest::new("foobar");
|
||||
/// let mut request = elefren::requests::UpdatePushRequest::new("foobar");
|
||||
/// request.follow(true);
|
||||
/// ```
|
||||
pub fn follow(&mut self, follow: bool) -> &mut Self {
|
||||
|
@ -278,11 +249,9 @@ impl UpdatePushRequest {
|
|||
|
||||
/// A flag that indicates if you want favourite notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// let mut request = UpdatePushRequest::new("foobar");
|
||||
/// let mut request = elefren::requests::UpdatePushRequest::new("foobar");
|
||||
/// request.favourite(true);
|
||||
/// ```
|
||||
pub fn favourite(&mut self, favourite: bool) -> &mut Self {
|
||||
|
@ -292,9 +261,8 @@ impl UpdatePushRequest {
|
|||
|
||||
/// A flag that indicates if you want reblog notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// let mut request = UpdatePushRequest::new("foobar");
|
||||
/// request.reblog(true);
|
||||
|
@ -306,9 +274,8 @@ impl UpdatePushRequest {
|
|||
|
||||
/// A flag that indicates if you want mention notifications pushed
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::requests::UpdatePushRequest;
|
||||
/// let mut request = UpdatePushRequest::new("foobar");
|
||||
/// request.mention(true);
|
||||
|
@ -326,7 +293,7 @@ impl UpdatePushRequest {
|
|||
}
|
||||
|
||||
pub(crate) fn build(&self) -> update_data::Form {
|
||||
use entities::push::{
|
||||
use crate::entities::push::{
|
||||
update_data::{Data, Form},
|
||||
Alerts,
|
||||
};
|
||||
|
@ -361,7 +328,7 @@ impl UpdatePushRequest {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use entities::push::{add_subscription, update_data, Alerts};
|
||||
use crate::entities::push::{add_subscription, update_data, Alerts};
|
||||
|
||||
#[test]
|
||||
fn test_keys_new() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use errors::Error;
|
||||
use crate::errors::Error;
|
||||
use serde::Serialize;
|
||||
use serde_qs;
|
||||
use std::{borrow::Cow, convert::Into};
|
||||
|
||||
|
@ -20,14 +21,13 @@ mod bool_qs_serialize {
|
|||
|
||||
/// Builder for making a client.statuses() call
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// use elefren::requests::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// request.only_media().pinned().since_id("foo");
|
||||
/// # assert_eq!(&request.to_querystring().expect("Couldn't serialize qs")[..], "?only_media=1&pinned=1&since_id=foo");
|
||||
/// assert_eq!(&request.to_querystring().expect("Couldn't serialize qs")[..], "?only_media=1&pinned=1&since_id=foo");
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
|
||||
pub struct StatusesRequest<'a> {
|
||||
|
@ -66,27 +66,18 @@ impl<'a> Into<Option<StatusesRequest<'a>>> for &'a mut StatusesRequest<'a> {
|
|||
|
||||
impl<'a> StatusesRequest<'a> {
|
||||
/// Construct a new `StatusesRequest` object
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let request = StatusesRequest::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Set the `?only_media=1` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(&request.only_media().to_querystring().expect("Couldn't serialize qs"), "?only_media=1");
|
||||
/// ```
|
||||
pub fn only_media(&mut self) -> &mut Self {
|
||||
self.only_media = true;
|
||||
self
|
||||
|
@ -94,12 +85,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?exclude_replies=1` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .exclude_replies()
|
||||
|
@ -115,12 +104,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?pinned=1` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .pinned()
|
||||
|
@ -136,12 +123,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?max_id=:max_id` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .max_id("foo")
|
||||
|
@ -157,12 +142,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?since_id=:since_id` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .since_id("foo")
|
||||
|
@ -178,12 +161,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?limit=:limit` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .limit(10)
|
||||
|
@ -199,12 +180,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Set the `?min_id=:min_id` flag for the .statuses() request
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .min_id("foobar")
|
||||
|
@ -220,12 +199,10 @@ impl<'a> StatusesRequest<'a> {
|
|||
|
||||
/// Turns this builder into a querystring
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::StatusesRequest;
|
||||
/// let mut request = StatusesRequest::new();
|
||||
/// let mut request = elefren::requests::StatusesRequest::new();
|
||||
/// assert_eq!(
|
||||
/// &request
|
||||
/// .limit(10)
|
||||
|
|
|
@ -3,35 +3,26 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use entities::account::{Credentials, MetadataField, UpdateSource};
|
||||
use errors::Result;
|
||||
use status_builder;
|
||||
use crate::{
|
||||
entities::account::{Credentials, MetadataField, UpdateSource},
|
||||
errors::Result,
|
||||
status_builder,
|
||||
};
|
||||
|
||||
/// Builder to pass to the Mastodon::update_credentials method
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::Data;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// use elefren::{prelude::*, status_builder::Visibility, UpdateCredsRequest};
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.privacy(Visibility::Unlisted);
|
||||
///
|
||||
/// let result = client.update_credentials(&mut builder)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// let result = client.update_credentials(&mut builder).unwrap();
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct UpdateCredsRequest {
|
||||
|
@ -49,10 +40,10 @@ pub struct UpdateCredsRequest {
|
|||
impl UpdateCredsRequest {
|
||||
/// Create a new UpdateCredsRequest
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -63,10 +54,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new display_name value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -80,10 +71,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new note value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -97,10 +88,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new avatar value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -116,10 +107,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new header value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -135,10 +126,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new privacy value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::{status_builder::Visibility, UpdateCredsRequest};
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -152,10 +143,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Set the new sensitive value
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -169,10 +160,10 @@ impl UpdateCredsRequest {
|
|||
|
||||
/// Add a metadata field
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// // extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
|
@ -202,7 +193,7 @@ impl UpdateCredsRequest {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use entities::account::{Credentials, MetadataField, UpdateSource};
|
||||
use crate::entities::account::{Credentials, MetadataField, UpdateSource};
|
||||
use status_builder::Visibility;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -8,13 +8,16 @@ use std::{
|
|||
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
|
||||
use errors::Error;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde::de::{self, Visitor};
|
||||
use crate::errors::Error;
|
||||
use serde::{
|
||||
de::{self, Visitor},
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
};
|
||||
|
||||
/// Represents a set of OAuth scopes
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use elefren::prelude::*;
|
||||
|
@ -64,15 +67,18 @@ impl<'de> Visitor<'de> for DeserializeScopesVisitor {
|
|||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where E: de::Error
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Scopes::from_str(v).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Scopes {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
|
||||
D: Deserializer<'de> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(DeserializeScopesVisitor)
|
||||
}
|
||||
}
|
||||
|
@ -81,15 +87,10 @@ impl Scopes {
|
|||
/// Represents all available oauth scopes: "read write follow push"
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::Scopes;
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::all();
|
||||
/// assert_eq!(&format!("{}", scope), "read write follow push");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn all() -> Scopes {
|
||||
Scopes::read_all() | Scopes::write_all() | Scopes::follow() | Scopes::push()
|
||||
|
@ -98,15 +99,10 @@ impl Scopes {
|
|||
/// Represents the full "read" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::Scopes;
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::read_all();
|
||||
/// assert_eq!(&format!("{}", scope), "read");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn read_all() -> Scopes {
|
||||
Scopes::_read(None)
|
||||
|
@ -115,15 +111,10 @@ impl Scopes {
|
|||
/// Represents a specific "read:___" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::{Read, Scopes};
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::read(Read::Accounts);
|
||||
/// assert_eq!(&format!("{}", scope), "read:accounts");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn read(subscope: Read) -> Scopes {
|
||||
Scopes::_read(Some(subscope))
|
||||
|
@ -132,15 +123,10 @@ impl Scopes {
|
|||
/// Represents the full "write" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::Scopes;
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::write_all();
|
||||
/// assert_eq!(&format!("{}", scope), "write");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn write_all() -> Scopes {
|
||||
Scopes::_write(None)
|
||||
|
@ -149,15 +135,10 @@ impl Scopes {
|
|||
/// Represents a specific "write:___" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::{Scopes, Write};
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::write(Write::Accounts);
|
||||
/// assert_eq!(&format!("{}", scope), "write:accounts");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn write(subscope: Write) -> Scopes {
|
||||
Scopes::_write(Some(subscope))
|
||||
|
@ -166,15 +147,10 @@ impl Scopes {
|
|||
/// Represents the "follow" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::Scopes;
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::follow();
|
||||
/// assert_eq!(&format!("{}", scope), "follow");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn follow() -> Scopes {
|
||||
Scopes::new(Scope::Follow)
|
||||
|
@ -183,15 +159,10 @@ impl Scopes {
|
|||
/// Represents the full "push" scope
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use std::error::Error;
|
||||
/// use elefren::scopes::Scopes;
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<Error>> {
|
||||
/// let scope = Scopes::push();
|
||||
/// assert_eq!(&format!("{}", scope), "push");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn push() -> Scopes {
|
||||
Scopes::new(Scope::Push)
|
||||
|
@ -199,7 +170,7 @@ impl Scopes {
|
|||
|
||||
/// Combines 2 scopes together
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use elefren::prelude::*;
|
||||
|
@ -764,7 +735,7 @@ mod tests {
|
|||
let expected = format!("\"{}\"", b);
|
||||
assert_eq!(&ser, &expected);
|
||||
|
||||
let des : Scopes = serde_json::from_str(&ser).expect("Couldn't deserialize Scopes");
|
||||
let des: Scopes = serde_json::from_str(&ser).expect("Couldn't deserialize Scopes");
|
||||
assert_eq!(&des, a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
use isolang::Language;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A builder pattern struct for constructing a status.
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// # use elefren::{Language, StatusBuilder};
|
||||
/// use elefren::{Language, StatusBuilder};
|
||||
///
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("a status")
|
||||
/// .sensitive(true)
|
||||
/// .spoiler_text("a CW")
|
||||
/// .language(Language::Eng)
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build().unwrap();
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct StatusBuilder {
|
||||
|
@ -33,27 +30,19 @@ pub struct StatusBuilder {
|
|||
impl StatusBuilder {
|
||||
/// Create a StatusBuilder object
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use elefren::status_builder::Visibility;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// # let data = Data {
|
||||
/// # base: "".into(),
|
||||
/// # client_id: "".into(),
|
||||
/// # client_secret: "".into(),
|
||||
/// # redirect: "".into(),
|
||||
/// # token: "".into(),
|
||||
/// # };
|
||||
/// # let client = Mastodon::from(data);
|
||||
/// use elefren::{status_builder::Visibility, prelude::*};
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("a status")
|
||||
/// .visibility(Visibility::Public)
|
||||
/// .build()?;
|
||||
/// client.new_status(status)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// client.new_status(status).unwrap();
|
||||
/// ```
|
||||
pub fn new() -> StatusBuilder {
|
||||
StatusBuilder::default()
|
||||
|
@ -61,14 +50,11 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the text for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// let status = StatusBuilder::new().status("awoooooo").build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new().status("awoooooo").build().unwrap();
|
||||
/// ```
|
||||
pub fn status<I: Into<String>>(&mut self, status: I) -> &mut Self {
|
||||
self.status = Some(status.into());
|
||||
|
@ -77,17 +63,15 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the in_reply_to_id for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("awooooo")
|
||||
/// .in_reply_to("12345")
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn in_reply_to<I: Into<String>>(&mut self, id: I) -> &mut Self {
|
||||
self.in_reply_to_id = Some(id.into());
|
||||
|
@ -96,14 +80,11 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the media_ids for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// let status = StatusBuilder::new().media_ids(&["foo", "bar"]).build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new().media_ids(&["foo", "bar"]).build().unwrap();
|
||||
/// ```
|
||||
pub fn media_ids<S: std::fmt::Display, I: IntoIterator<Item = S>>(
|
||||
&mut self,
|
||||
|
@ -115,36 +96,15 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the sensitive attribute for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .media_ids(&["foo", "bar"])
|
||||
/// .sensitive(true)
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn sensitive(&mut self, sensitive: bool) -> &mut Self {
|
||||
self.sensitive = Some(sensitive);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the spoiler text/CW for the post
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("awoooo!!")
|
||||
/// .spoiler_text("awoo inside")
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn spoiler_text<I: Into<String>>(&mut self, spoiler_text: I) -> &mut Self {
|
||||
self.spoiler_text = Some(spoiler_text.into());
|
||||
|
@ -155,7 +115,7 @@ impl StatusBuilder {
|
|||
///
|
||||
/// This is a Pleroma and Glitch-soc extension of the API.
|
||||
///
|
||||
/// # Possible values
|
||||
/// // Possible values
|
||||
/// - `text/plain`
|
||||
/// - `text/html`
|
||||
/// - `text/markdown`
|
||||
|
@ -163,17 +123,15 @@ impl StatusBuilder {
|
|||
///
|
||||
/// The set of supported content types may vary by server.
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("<b>thicc</b>")
|
||||
/// .content_type("text/html")
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn content_type<I: Into<String>>(&mut self, content_type: I) -> &mut Self {
|
||||
self.content_type = Some(content_type.into());
|
||||
|
@ -182,18 +140,15 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the visibility for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use elefren::status_builder::Visibility;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// use elefren::{prelude::*, status_builder::Visibility};
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("awooooooo")
|
||||
/// .visibility(Visibility::Public)
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn visibility(&mut self, visibility: Visibility) -> &mut Self {
|
||||
self.visibility = Some(visibility);
|
||||
|
@ -202,34 +157,43 @@ impl StatusBuilder {
|
|||
|
||||
/// Set the language for the post
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # use elefren::Language;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// use elefren::{Language, prelude::*};
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("awoo!!!!")
|
||||
/// .language(Language::Eng)
|
||||
/// .build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn language(&mut self, language: Language) -> &mut Self {
|
||||
self.language = Some(language);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the status as "sensitive".
|
||||
/// ```
|
||||
/// use elefren::StatusBuilder;
|
||||
///
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("a sensitive matter")
|
||||
/// .sensitive(true)
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn sensitive(&mut self, flag: bool) -> &mut Self {
|
||||
self.sensitive = Some(flag);
|
||||
self
|
||||
}
|
||||
|
||||
/// Constructs a NewStatus
|
||||
///
|
||||
/// # Example
|
||||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use elefren::prelude::*;
|
||||
/// # fn main() -> Result<(), elefren::Error> {
|
||||
/// let status = StatusBuilder::new().status("awoo!").build()?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// use elefren::prelude::*;
|
||||
/// let status = StatusBuilder::new().status("awoo!").build().unwrap();
|
||||
/// ```
|
||||
pub fn build(&self) -> Result<NewStatus, crate::Error> {
|
||||
if self.status.is_none() && self.media_ids.is_none() {
|
||||
|
|
Loading…
Reference in New Issue