Moved Display impl from types to cli crate. added pager to feed.
This commit is contained in:
parent
31faf60285
commit
2fcfbe9e67
|
@ -117,7 +117,7 @@ dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim",
|
"strsim",
|
||||||
"textwrap",
|
"textwrap 0.11.0",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
|
@ -126,12 +126,15 @@ dependencies = [
|
||||||
name = "cli"
|
name = "cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"minus",
|
||||||
"rpassword",
|
"rpassword",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"socialvoid",
|
"socialvoid",
|
||||||
"socialvoid_rawclient",
|
"socialvoid_rawclient",
|
||||||
|
"socialvoid_types",
|
||||||
"structopt",
|
"structopt",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -161,6 +164,31 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"crossterm_winapi",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"signal-hook",
|
||||||
|
"signal-hook-mio",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm_winapi"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -607,6 +635,17 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minus"
|
||||||
|
version = "4.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0cfa68574733d70c28177f9608f2cd10f298ed109f55a900078886a90cbc265"
|
||||||
|
dependencies = [
|
||||||
|
"crossterm",
|
||||||
|
"textwrap 0.13.4",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.7.13"
|
version = "0.7.13"
|
||||||
|
@ -1157,6 +1196,27 @@ dependencies = [
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-mio"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"signal-hook",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -1215,7 +1275,6 @@ dependencies = [
|
||||||
name = "socialvoid_types"
|
name = "socialvoid_types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1295,6 +1354,35 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.43"
|
version = "0.1.43"
|
||||||
|
|
|
@ -12,9 +12,12 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
"socialvoid" = { path = "../client" }
|
"socialvoid" = { path = "../client" }
|
||||||
"socialvoid_rawclient" = { path = "../rawclient" }
|
"socialvoid_rawclient" = { path = "../rawclient" }
|
||||||
|
"socialvoid_types" = { path = "../types" }
|
||||||
structopt = "0.3.23"
|
structopt = "0.3.23"
|
||||||
serde = { version = "1.0", features = ["derive"]}
|
serde = { version = "1.0", features = ["derive"]}
|
||||||
serde_json = "1.0.67"
|
serde_json = "1.0.67"
|
||||||
shellexpand = "2.1.0"
|
shellexpand = "2.1.0"
|
||||||
tokio = {version = "1.11.0", features = ["full"]}
|
tokio = {version = "1.11.0", features = ["full"]}
|
||||||
rpassword = "5.0.1"
|
rpassword = "5.0.1"
|
||||||
|
minus = { version = "4.0.2", features = ["static_output"] }
|
||||||
|
chrono = "0.4.19"
|
|
@ -0,0 +1,145 @@
|
||||||
|
use socialvoid_types::*;
|
||||||
|
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
|
pub struct SVPost(Post);
|
||||||
|
pub struct SVProfile(Profile);
|
||||||
|
|
||||||
|
impl std::convert::From<Post> for SVPost {
|
||||||
|
fn from(post: Post) -> Self {
|
||||||
|
Self(post)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Profile> for SVProfile {
|
||||||
|
fn from(profile: Profile) -> Self {
|
||||||
|
Self(profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for SVPost {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Post Type: {}
|
||||||
|
ID: {}
|
||||||
|
Author: {}
|
||||||
|
Source: {}
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
{} attachment(s)
|
||||||
|
Posted on: {}
|
||||||
|
Likes: {}, Reposts: {}, Quotes: {}, Replies: {},
|
||||||
|
Flags: ",
|
||||||
|
match self.0.post_type {
|
||||||
|
PostType::Reply => format!(
|
||||||
|
"Reply to <{}>",
|
||||||
|
match &self.0.reply_to_post {
|
||||||
|
Some(reply_to_post) => reply_to_post.id.clone(),
|
||||||
|
None => String::new(),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
PostType::Quote => format!(
|
||||||
|
"Quoted post <{}>",
|
||||||
|
match &self.0.quoted_post.as_ref() {
|
||||||
|
Some(quoted_post) => quoted_post.id.clone(),
|
||||||
|
None => String::new(),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
PostType::Repost => format!(
|
||||||
|
"Reposted post <{}>",
|
||||||
|
match &self.0.reposted_post.as_ref() {
|
||||||
|
Some(reposted_post) => reposted_post.id.clone(),
|
||||||
|
None => String::new(),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_ => format!("{:?}", self.0.post_type),
|
||||||
|
},
|
||||||
|
self.0.id,
|
||||||
|
self.0
|
||||||
|
.peer
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| x.username.to_string())
|
||||||
|
.unwrap_or_else(|| "<unavailable>".to_string()),
|
||||||
|
self.0
|
||||||
|
.source
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&"<not applicable>".to_owned()),
|
||||||
|
self.0.text.as_ref().unwrap_or(&"<no text>".to_string()),
|
||||||
|
self.0.attachments.len(), //TODO: maybe show the document IDs
|
||||||
|
{
|
||||||
|
let d = UNIX_EPOCH + Duration::from_secs(self.0.posted_timestamp);
|
||||||
|
// Create DateTime from SystemTime
|
||||||
|
let datetime = DateTime::<Utc>::from(d);
|
||||||
|
// Formats the combined date and time with the specified format string.
|
||||||
|
datetime.format("%Y-%m-%d %H:%M:%S.%f").to_string()
|
||||||
|
},
|
||||||
|
self.0
|
||||||
|
.like_count
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.unwrap_or_else(|| "<not applicable>".to_string()),
|
||||||
|
self.0
|
||||||
|
.repost_count
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.unwrap_or_else(|| "<not applicable>".to_string()),
|
||||||
|
self.0
|
||||||
|
.quote_count
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.unwrap_or_else(|| "<not applicable>".to_string()),
|
||||||
|
self.0
|
||||||
|
.reply_count
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.unwrap_or_else(|| "<not applicable>".to_string()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for SVProfile {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"First Name: {}
|
||||||
|
{}
|
||||||
|
Name: {}
|
||||||
|
{}
|
||||||
|
{}
|
||||||
|
{}
|
||||||
|
Followers: {}
|
||||||
|
Following: {}
|
||||||
|
Display Picture: {}",
|
||||||
|
self.0.first_name,
|
||||||
|
self.0
|
||||||
|
.last_name
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| format!("Last Name: {}", x))
|
||||||
|
.unwrap_or_else(|| String::from("[No last name set]")),
|
||||||
|
self.0.name,
|
||||||
|
self.0
|
||||||
|
.biography
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| format!("Biography: {}", x))
|
||||||
|
.unwrap_or_else(|| String::from("[No biography set]")),
|
||||||
|
self.0
|
||||||
|
.location
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| format!("Location: {}", x))
|
||||||
|
.unwrap_or_else(|| String::from("[No location set]")),
|
||||||
|
self.0
|
||||||
|
.url
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| format!("URL: {}", x))
|
||||||
|
.unwrap_or_else(|| String::from("[No URL set]")),
|
||||||
|
self.0.followers_count,
|
||||||
|
self.0.following_count,
|
||||||
|
if self.0.display_picture_sizes.is_empty() {
|
||||||
|
String::from("not set")
|
||||||
|
} else {
|
||||||
|
let count = self.0.display_picture_sizes.len();
|
||||||
|
let name = &self.0.display_picture_sizes[0].document.file_name;
|
||||||
|
format!("'{}' ({} sizes available)", name, count)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
use socialvoid::session::RegisterRequest;
|
use socialvoid::session::RegisterRequest;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
mod entities;
|
||||||
mod error;
|
mod error;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
use crate::entities::*;
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
use error::MyFriendlyError;
|
use error::MyFriendlyError;
|
||||||
|
|
||||||
|
@ -166,7 +168,7 @@ async fn main() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SocialVoidCommand::Profile { peer } => match sv.network.get_profile(peer).await {
|
SocialVoidCommand::Profile { peer } => match sv.network.get_profile(peer).await {
|
||||||
Ok(profile) => println!("{}", profile),
|
Ok(profile) => println!("{}", SVProfile::from(profile)),
|
||||||
Err(err) => println!(
|
Err(err) => println!(
|
||||||
"An error occurred while trying to get the profile.\n{}",
|
"An error occurred while trying to get the profile.\n{}",
|
||||||
MyFriendlyError::from(err)
|
MyFriendlyError::from(err)
|
||||||
|
@ -196,10 +198,19 @@ async fn main() {
|
||||||
}
|
}
|
||||||
SocialVoidCommand::Feed { page } => match sv.timeline.retrieve_feed(page).await {
|
SocialVoidCommand::Feed { page } => match sv.timeline.retrieve_feed(page).await {
|
||||||
Ok(feed) => {
|
Ok(feed) => {
|
||||||
for post in feed.iter() {
|
let mut pager = minus::Pager::new().unwrap();
|
||||||
println!("================\n{}", post);
|
|
||||||
|
let n_posts = feed.len();
|
||||||
|
for post in feed.into_iter() {
|
||||||
|
let post = SVPost::from(post);
|
||||||
|
pager.push_str(format!("================\n{}", post));
|
||||||
}
|
}
|
||||||
println!("----Retrieved {} post(s) from the timeline.\n", feed.len());
|
pager.push_str(format!(
|
||||||
|
"----Retrieved {} post(s) from the timeline.\n",
|
||||||
|
n_posts
|
||||||
|
));
|
||||||
|
pager.set_prompt("Feed - Socialvoid");
|
||||||
|
minus::page_all(pager).expect("Error with pager");
|
||||||
}
|
}
|
||||||
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
||||||
},
|
},
|
||||||
|
@ -212,7 +223,7 @@ async fn main() {
|
||||||
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
||||||
},
|
},
|
||||||
SocialVoidCommand::GetPost { post_id } => match sv.timeline.get_post(post_id).await {
|
SocialVoidCommand::GetPost { post_id } => match sv.timeline.get_post(post_id).await {
|
||||||
Ok(post) => println!("{}", post),
|
Ok(post) => println!("{}", SVPost::from(post)),
|
||||||
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
Err(err) => println!("{}", MyFriendlyError::from(err)),
|
||||||
},
|
},
|
||||||
SocialVoidCommand::DeletePost { post_id } => match sv.timeline.delete(post_id).await {
|
SocialVoidCommand::DeletePost { post_id } => match sv.timeline.delete(post_id).await {
|
||||||
|
|
|
@ -8,5 +8,4 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"]}
|
serde = { version = "1.0", features = ["derive"]}
|
||||||
serde_json = "1.0.67"
|
serde_json = "1.0.67"
|
||||||
tokio = {version = "1.11.0", features = ["full"]}
|
tokio = {version = "1.11.0", features = ["full"]}
|
||||||
chrono = "0.4.19"
|
|
142
types/src/lib.rs
142
types/src/lib.rs
|
@ -1,6 +1,4 @@
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct SessionIdentification {
|
pub struct SessionIdentification {
|
||||||
|
@ -29,9 +27,9 @@ pub enum PeerType {
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct DisplayPictureSize {
|
pub struct DisplayPictureSize {
|
||||||
width: u32,
|
pub width: u32,
|
||||||
height: u32,
|
pub height: u32,
|
||||||
document: Document,
|
pub document: Document,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -116,15 +114,15 @@ pub struct ServerInformation {
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Profile {
|
pub struct Profile {
|
||||||
first_name: String,
|
pub first_name: String,
|
||||||
last_name: Option<String>,
|
pub last_name: Option<String>,
|
||||||
name: String,
|
pub name: String,
|
||||||
biography: Option<String>,
|
pub biography: Option<String>,
|
||||||
location: Option<String>,
|
pub location: Option<String>,
|
||||||
url: Option<String>,
|
pub url: Option<String>,
|
||||||
followers_count: u32,
|
pub followers_count: u32,
|
||||||
following_count: u32,
|
pub following_count: u32,
|
||||||
display_picture_sizes: Vec<DisplayPictureSize>,
|
pub display_picture_sizes: Vec<DisplayPictureSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Relationship of a peer with another peer.
|
/// Relationship of a peer with another peer.
|
||||||
|
@ -176,119 +174,3 @@ pub enum PostType {
|
||||||
Quote,
|
Quote,
|
||||||
Repost,
|
Repost,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Post {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"Post Type: {}
|
|
||||||
ID: {}
|
|
||||||
Author: {}
|
|
||||||
Source: {}
|
|
||||||
----
|
|
||||||
{}
|
|
||||||
----
|
|
||||||
{} attachment(s)
|
|
||||||
Posted on: {}
|
|
||||||
Likes: {}, Reposts: {}, Quotes: {}, Replies: {},
|
|
||||||
Flags: ",
|
|
||||||
match self.post_type {
|
|
||||||
PostType::Reply => format!(
|
|
||||||
"Reply to <{}>",
|
|
||||||
match &self.reply_to_post {
|
|
||||||
Some(reply_to_post) => reply_to_post.id.clone(),
|
|
||||||
None => String::new(),
|
|
||||||
}
|
|
||||||
),
|
|
||||||
PostType::Quote => format!(
|
|
||||||
"Quoted post <{}>",
|
|
||||||
match &self.quoted_post.as_ref() {
|
|
||||||
Some(quoted_post) => quoted_post.id.clone(),
|
|
||||||
None => String::new(),
|
|
||||||
}
|
|
||||||
),
|
|
||||||
PostType::Repost => format!(
|
|
||||||
"Reposted post <{}>",
|
|
||||||
match &self.reposted_post.as_ref() {
|
|
||||||
Some(reposted_post) => reposted_post.id.clone(),
|
|
||||||
None => String::new(),
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_ => format!("{:?}", self.post_type),
|
|
||||||
},
|
|
||||||
self.id,
|
|
||||||
self.peer
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| format!("{}", x.username))
|
|
||||||
.unwrap_or("<unavailable>".to_string()),
|
|
||||||
self.source
|
|
||||||
.as_ref()
|
|
||||||
.unwrap_or(&"<not applicable>".to_owned()),
|
|
||||||
self.text.as_ref().unwrap_or(&"<no text>".to_string()),
|
|
||||||
self.attachments.len(), //TODO: maybe show the document IDs
|
|
||||||
{
|
|
||||||
let d = UNIX_EPOCH + Duration::from_secs(self.posted_timestamp);
|
|
||||||
// Create DateTime from SystemTime
|
|
||||||
let datetime = DateTime::<Utc>::from(d);
|
|
||||||
// Formats the combined date and time with the specified format string.
|
|
||||||
datetime.format("%Y-%m-%d %H:%M:%S.%f").to_string()
|
|
||||||
},
|
|
||||||
self.like_count
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.unwrap_or("<not applicable>".to_string()),
|
|
||||||
self.repost_count
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.unwrap_or("<not applicable>".to_string()),
|
|
||||||
self.quote_count
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.unwrap_or("<not applicable>".to_string()),
|
|
||||||
self.reply_count
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.unwrap_or("<not applicable>".to_string()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for Profile {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"First Name: {}
|
|
||||||
{}
|
|
||||||
Name: {}
|
|
||||||
{}
|
|
||||||
{}
|
|
||||||
{}
|
|
||||||
Followers: {}
|
|
||||||
Following: {}
|
|
||||||
Display Picture: {}",
|
|
||||||
self.first_name,
|
|
||||||
self.last_name
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| format!("Last Name: {}", x))
|
|
||||||
.unwrap_or_else(|| String::from("[No last name set]")),
|
|
||||||
self.name,
|
|
||||||
self.biography
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| format!("Biography: {}", x))
|
|
||||||
.unwrap_or_else(|| String::from("[No biography set]")),
|
|
||||||
self.location
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| format!("Location: {}", x))
|
|
||||||
.unwrap_or_else(|| String::from("[No location set]")),
|
|
||||||
self.url
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| format!("URL: {}", x))
|
|
||||||
.unwrap_or_else(|| String::from("[No URL set]")),
|
|
||||||
self.followers_count,
|
|
||||||
self.following_count,
|
|
||||||
if self.display_picture_sizes.is_empty() {
|
|
||||||
String::from("not set")
|
|
||||||
} else {
|
|
||||||
let count = self.display_picture_sizes.len();
|
|
||||||
let name = &self.display_picture_sizes[0].document.file_name;
|
|
||||||
format!("'{}' ({} sizes available)", name, count)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue