From 0ad1e3741ca8a2419433986da2e60395289ec5e9 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Tue, 4 Sep 2018 14:44:23 -0400 Subject: [PATCH] Allow the user to update their profile metadata fields Closes #54 --- src/entities/account.rs | 40 +++++++++++++++++++++++++++++- src/requests/update_credentials.rs | 36 +++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/entities/account.rs b/src/entities/account.rs index 2411c02..604f9fd 100644 --- a/src/entities/account.rs +++ b/src/entities/account.rs @@ -45,6 +45,26 @@ pub struct Account { /// If the owner decided to switch accounts, new account is in /// this attribute pub moved: Option>, + /// List of profile metadata fields + pub fields: Option>, + /// Boolean indicating whether this account is a bot or not + pub bot: Option, +} + +/// A single name: value pair from a user's profile +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] +pub struct MetadataField { + name: String, + value: String, +} + +impl MetadataField { + pub(crate) fn new(name: &str, value: &str) -> MetadataField { + MetadataField { + name: name.into(), + value: value.into(), + } + } } /// An extra object given from `verify_credentials` giving defaults about a user @@ -54,6 +74,7 @@ pub struct Source { #[serde(deserialize_with = "string_or_bool")] sensitive: bool, note: String, + fields: Vec, } fn string_or_bool<'de, D: Deserializer<'de>>(val: D) -> ::std::result::Result { @@ -81,7 +102,7 @@ fn string_or_bool<'de, D: Deserializer<'de>>(val: D) -> ::std::result::Result, @@ -101,4 +122,21 @@ pub(crate) struct Credentials { pub(crate) header: Option, #[serde(skip_serializing_if = "Option::is_none")] pub(crate) source: Option, + #[serde(serialize_with = "fields_attributes_ser::ser")] + pub(crate) fields_attributes: Vec, +} + +mod fields_attributes_ser { + use super::*; + use serde::ser::{SerializeMap, Serializer}; + pub(crate) fn ser(attrs: &Vec, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(attrs.len()))?; + for (i, field) in attrs.iter().enumerate() { + map.serialize_entry(&i, &field)?; + } + map.end() + } } diff --git a/src/requests/update_credentials.rs b/src/requests/update_credentials.rs index d0e0fb8..7784cc3 100644 --- a/src/requests/update_credentials.rs +++ b/src/requests/update_credentials.rs @@ -3,7 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -use entities::account::{Credentials, UpdateSource}; +use entities::account::{Credentials, MetadataField, UpdateSource}; use errors::Result; use status_builder; @@ -39,6 +39,7 @@ pub struct UpdateCredsRequest { note: Option, avatar: Option, header: Option, + field_attributes: Vec, // UpdateSource fields privacy: Option, @@ -166,6 +167,23 @@ impl UpdateCredsRequest { self } + /// Add a metadata field + /// + /// # Example + /// + /// ``` + /// # extern crate elefren; + /// use elefren::UpdateCredsRequest; + /// + /// let mut builder = UpdateCredsRequest::new(); + /// + /// builder.field_attribute("some key", "some value"); + /// ``` + pub fn field_attribute(&mut self, name: &str, value: &str) -> &mut Self { + self.field_attributes.push(MetadataField::new(name, value)); + self + } + pub(crate) fn build(&mut self) -> Result { Ok(Credentials { display_name: self.display_name.clone(), @@ -176,6 +194,7 @@ impl UpdateCredsRequest { privacy: self.privacy.clone(), sensitive: self.sensitive.clone(), }), + fields_attributes: self.field_attributes.clone(), }) } } @@ -183,7 +202,7 @@ impl UpdateCredsRequest { #[cfg(test)] mod tests { use super::*; - use entities::account::{Credentials, UpdateSource}; + use entities::account::{Credentials, MetadataField, UpdateSource}; use status_builder::Visibility; #[test] @@ -275,6 +294,19 @@ mod tests { ); } + #[test] + fn test_update_creds_request_field_attribute() { + let mut builder = UpdateCredsRequest::new(); + builder.field_attribute("foo", "bar"); + assert_eq!( + builder, + UpdateCredsRequest { + field_attributes: vec![MetadataField::new("foo", "bar")], + ..Default::default() + } + ); + } + #[test] fn test_update_creds_request_build() { let mut builder = UpdateCredsRequest::new();