feat(update_credentials): Implement UpdateCredsRequest
This will now allow a user to actually call the MastodonClient::update_credentials method
This commit is contained in:
+21
-128
@@ -1,10 +1,9 @@
|
||||
//! A module containing everything relating to a account returned from the api.
|
||||
|
||||
use chrono::prelude::*;
|
||||
use reqwest::multipart::Form;
|
||||
use serde::de::{self, Deserialize, Deserializer, Unexpected};
|
||||
use std::path::Path;
|
||||
use Result;
|
||||
use status_builder;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A struct representing an Account.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
@@ -51,7 +50,7 @@ pub struct Account {
|
||||
/// An extra object given from `verify_credentials` giving defaults about a user
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Source {
|
||||
privacy: ::status_builder::Visibility,
|
||||
privacy: status_builder::Visibility,
|
||||
#[serde(deserialize_with = "string_or_bool")]
|
||||
sensitive: bool,
|
||||
note: String,
|
||||
@@ -82,130 +81,24 @@ fn string_or_bool<'de, D: Deserializer<'de>>(val: D) -> ::std::result::Result<bo
|
||||
})
|
||||
}
|
||||
|
||||
/// Data structure used for updating user credentials
|
||||
#[derive(Debug)]
|
||||
pub struct CredentialsBuilder<'a> {
|
||||
display_name: Option<&'a str>,
|
||||
note: Option<&'a str>,
|
||||
avatar: Option<&'a Path>,
|
||||
header: Option<&'a Path>,
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize)]
|
||||
pub(crate) struct UpdateSource {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) privacy: Option<status_builder::Visibility>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
impl<'a> CredentialsBuilder<'a> {
|
||||
/// Turns a `CredentialsForm` into a form suitable for PUTing to the
|
||||
/// endpoint
|
||||
pub fn into_form(self) -> Result<Form> {
|
||||
let mut form = Form::new();
|
||||
macro_rules! add_to_form {
|
||||
($key:ident : Text; $($rest:tt)*) => {{
|
||||
if let Some(val) = self.$key {
|
||||
form = form.text(stringify!($key), val.to_owned());
|
||||
}
|
||||
|
||||
add_to_form!{$($rest)*}
|
||||
}};
|
||||
|
||||
($key:ident : File; $($rest:tt)*) => {{
|
||||
if let Some(val) = self.$key {
|
||||
form = form.file(stringify!($key), val)?;
|
||||
}
|
||||
|
||||
add_to_form!{$($rest)*}
|
||||
}};
|
||||
|
||||
() => {}
|
||||
}
|
||||
|
||||
add_to_form! {
|
||||
display_name: Text;
|
||||
note: Text;
|
||||
avatar: File;
|
||||
header: File;
|
||||
}
|
||||
|
||||
Ok(form)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[test]
|
||||
fn test_credentials_builder_to_form() {
|
||||
let avatar = NamedTempFile::new().expect("Couldn't make avatar file");
|
||||
let header = NamedTempFile::new().expect("Couldn't make header file");
|
||||
let tests = [
|
||||
(None, None, None, None),
|
||||
(Some("my-display-name"), None, None, None),
|
||||
(None, Some("my-note"), None, None),
|
||||
(None, None, Some(avatar.path().clone()), None),
|
||||
(None, None, None, Some(header.path().clone())),
|
||||
(Some("my-display-name"), Some("my-note"), None, None),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
None,
|
||||
Some(avatar.path().clone()),
|
||||
None,
|
||||
),
|
||||
(None, Some("my-note"), Some(avatar.path().clone()), None),
|
||||
(None, Some("my-note"), None, Some(header.path().clone())),
|
||||
(
|
||||
None,
|
||||
None,
|
||||
Some(avatar.path().clone()),
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
None,
|
||||
None,
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
Some("my-note"),
|
||||
Some(avatar.path().clone()),
|
||||
None,
|
||||
),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
Some("my-note"),
|
||||
None,
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
None,
|
||||
Some(avatar.path().clone()),
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
(
|
||||
None,
|
||||
Some("my-note"),
|
||||
Some(avatar.path().clone()),
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
(
|
||||
Some("my-display-name"),
|
||||
Some("my-note"),
|
||||
Some(avatar.path().clone()),
|
||||
Some(header.path().clone()),
|
||||
),
|
||||
];
|
||||
|
||||
for test in tests.into_iter() {
|
||||
let (display_name, note, avatar, header) = test;
|
||||
let credentials_builder = CredentialsBuilder {
|
||||
display_name: *display_name,
|
||||
note: *note,
|
||||
avatar: *avatar,
|
||||
header: *header,
|
||||
};
|
||||
let _form = credentials_builder
|
||||
.into_form()
|
||||
.expect("could not create form");
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
pub(crate) struct Credentials {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) display_name: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) note: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) avatar: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) header: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) source: Option<UpdateSource>,
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ pub struct Empty {}
|
||||
/// modules:
|
||||
pub mod prelude {
|
||||
pub use super::{
|
||||
account::{Account, CredentialsBuilder, Source},
|
||||
account::{Account, Source},
|
||||
attachment::{Attachment, MediaType},
|
||||
card::Card,
|
||||
context::Context,
|
||||
|
||||
+3
-2
@@ -80,7 +80,7 @@ pub use data::Data;
|
||||
pub use errors::{ApiError, Error, Result};
|
||||
pub use mastodon_client::MastodonClient;
|
||||
pub use registration::Registration;
|
||||
pub use requests::statuses::StatusesRequest;
|
||||
pub use requests::{StatusesRequest, UpdateCredsRequest};
|
||||
pub use status_builder::StatusBuilder;
|
||||
|
||||
/// Registering your App
|
||||
@@ -207,7 +207,8 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
||||
(delete) delete_status: "statuses/{}" => Empty,
|
||||
}
|
||||
|
||||
fn update_credentials(&self, changes: CredentialsBuilder) -> Result<Account> {
|
||||
fn update_credentials(&self, builder: &mut UpdateCredsRequest) -> Result<Account> {
|
||||
let changes = builder.build()?;
|
||||
let url = self.route("/api/v1/accounts/update_credentials");
|
||||
let response = self.send(self.client.patch(&url).json(&changes))?;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use entities::prelude::*;
|
||||
use errors::Result;
|
||||
use http_send::{HttpSend, HttpSender};
|
||||
use page::Page;
|
||||
use requests::statuses::StatusesRequest;
|
||||
use requests::{StatusesRequest, UpdateCredsRequest};
|
||||
use status_builder::StatusBuilder;
|
||||
|
||||
/// Represents the set of methods that a Mastodon Client can do, so that
|
||||
@@ -172,7 +172,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
||||
unimplemented!("This method was not implemented");
|
||||
}
|
||||
/// PATCH /api/v1/accounts/update_credentials
|
||||
fn update_credentials(&self, changes: CredentialsBuilder) -> Result<Account> {
|
||||
fn update_credentials(&self, builder: &mut UpdateCredsRequest) -> Result<Account> {
|
||||
unimplemented!("This method was not implemented");
|
||||
}
|
||||
/// POST /api/v1/statuses
|
||||
|
||||
+7
-2
@@ -1,2 +1,7 @@
|
||||
/// Data structures for the MastodonClient::statuses method
|
||||
pub mod statuses;
|
||||
/// Data structure for the MastodonClient::statuses method
|
||||
pub use self::statuses::StatusesRequest;
|
||||
/// Data structure for the MastodonClient::update_credentials method
|
||||
pub use self::update_credentials::UpdateCredsRequest;
|
||||
|
||||
mod statuses;
|
||||
mod update_credentials;
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
use std::{
|
||||
fmt::Display,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use entities::account::{Credentials, UpdateSource};
|
||||
use errors::Result;
|
||||
use status_builder;
|
||||
|
||||
/// Builder to pass to the Mastodon::update_credentials method
|
||||
///
|
||||
/// # 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 client = Mastodon::from(data);
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.privacy(Visibility::Unlisted);
|
||||
///
|
||||
/// let result = client.update_credentials(&mut builder)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct UpdateCredsRequest {
|
||||
display_name: Option<String>,
|
||||
note: Option<String>,
|
||||
avatar: Option<PathBuf>,
|
||||
header: Option<PathBuf>,
|
||||
|
||||
// UpdateSource fields
|
||||
privacy: Option<status_builder::Visibility>,
|
||||
sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
impl UpdateCredsRequest {
|
||||
/// Create a new UpdateCredsRequest
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
/// ```
|
||||
pub fn new() -> UpdateCredsRequest {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Set the new display_name value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.display_name("my new display name");
|
||||
/// ```
|
||||
pub fn display_name<D: Display>(&mut self, name: D) -> &mut Self {
|
||||
self.display_name = Some(name.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the new note value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.note("my new note");
|
||||
/// ```
|
||||
pub fn note<D: Display>(&mut self, note: D) -> &mut Self {
|
||||
self.note = Some(note.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the new avatar value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.avatar("/path/to/my/new/avatar");
|
||||
/// ```
|
||||
pub fn avatar<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
|
||||
let path = path.as_ref();
|
||||
let path = path.to_path_buf();
|
||||
self.avatar = Some(path);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the new header value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.header("/path/to/my/new/header");
|
||||
/// ```
|
||||
pub fn header<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
|
||||
let path = path.as_ref();
|
||||
let path = path.to_path_buf();
|
||||
self.header = Some(path);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the new privacy value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::{status_builder::Visibility, UpdateCredsRequest};
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.privacy(Visibility::Public);
|
||||
/// ```
|
||||
pub fn privacy(&mut self, privacy: status_builder::Visibility) -> &mut Self {
|
||||
self.privacy = Some(privacy);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the new sensitive value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate elefren;
|
||||
/// use elefren::UpdateCredsRequest;
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.sensitive(true);
|
||||
/// ```
|
||||
pub fn sensitive(&mut self, sensitive: bool) -> &mut Self {
|
||||
self.sensitive = Some(sensitive);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build(&mut self) -> Result<Credentials> {
|
||||
Ok(Credentials {
|
||||
display_name: self.display_name.clone(),
|
||||
note: self.note.clone(),
|
||||
avatar: self.avatar.clone(),
|
||||
header: self.avatar.clone(),
|
||||
source: Some(UpdateSource {
|
||||
privacy: self.privacy.clone(),
|
||||
sensitive: self.sensitive.clone(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use status_builder::Visibility;
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_new() {
|
||||
let builder = UpdateCredsRequest::new();
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_display_name() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.display_name("foo");
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
display_name: Some("foo".into()),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_note() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.note("foo");
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
note: Some("foo".into()),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_avatar() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.avatar("/path/to/avatar.png");
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
avatar: Some(Path::new("/path/to/avatar.png").to_path_buf()),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_header() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.header("/path/to/header.png");
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
header: Some(Path::new("/path/to/header.png").to_path_buf()),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_privacy() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.privacy(Visibility::Public);
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
privacy: Some(Visibility::Public),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_sensitive() {
|
||||
let mut builder = UpdateCredsRequest::new();
|
||||
builder.sensitive(true);
|
||||
assert_eq!(
|
||||
builder,
|
||||
UpdateCredsRequest {
|
||||
sensitive: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user