From 97f030b15321bb22274fa2807da445aa5dfc5512 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Sat, 4 Mar 2023 19:03:17 -0800 Subject: cli: improve 'pretty' output styling --- adenosine-cli/src/pretty.rs | 62 ++++++++++++++++++++++++++++++++++++++++--- adenosine/src/app_bsky/mod.rs | 21 +++++++++++---- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/adenosine-cli/src/pretty.rs b/adenosine-cli/src/pretty.rs index 306c056..3d260a3 100644 --- a/adenosine-cli/src/pretty.rs +++ b/adenosine-cli/src/pretty.rs @@ -1,19 +1,71 @@ -use adenosine::app_bsky::PostView; +use adenosine::app_bsky::{FeedPostView, PostView, ThreadPostView}; use anyhow::Result; use std::io::Write; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; +pub fn pp_thread_post_view(tpv: &ThreadPostView) -> Result<()> { + // TODO: this could do better + if let Some(parent) = &tpv.parent { + pp_thread_post_view(&parent)?; + }; + if let Some(not_found) = &tpv.notFound { + if *not_found == true { + let mut stdout = StandardStream::stdout(ColorChoice::Always); + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?; + writeln!( + &mut stdout, + "thread post not found: {}\n", + tpv.uri.as_ref().expect("URI for post-not-found") + )?; + stdout.reset()?; + } + } + if let Some(post) = &tpv.post { + pp_post_view(&post)?; + } + if let Some(replies) = &tpv.replies { + for child in replies { + pp_thread_post_view(&child)?; + } + }; + Ok(()) +} + +pub fn pp_feed_post_view(fpv: &FeedPostView) -> Result<()> { + let mut stdout = StandardStream::stdout(ColorChoice::Always); + + if let Some(repost) = &fpv.reason { + stdout.set_color(ColorSpec::new().set_dimmed(true).set_italic(true))?; + write!(&mut stdout, "re-posted by ")?; + stdout.set_color( + ColorSpec::new() + .set_fg(Some(Color::Yellow)) + .set_dimmed(true) + .set_italic(true), + )?; + writeln!(&mut stdout, "@{}", repost.by.handle)?; + stdout.reset()?; + } + + pp_post_view(&fpv.post) +} + pub fn pp_post_view(pv: &PostView) -> Result<()> { let mut stdout = StandardStream::stdout(ColorChoice::Always); - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?; + if let Some(reply_to) = &pv.record.reply { + stdout.set_color(ColorSpec::new().set_dimmed(true).set_italic(true))?; + writeln!(&mut stdout, "reply to {}", reply_to.parent.uri)?; + stdout.reset()?; + } + + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?; write!(&mut stdout, "@{:<54.54}", pv.author.handle)?; stdout.reset()?; stdout.set_color(ColorSpec::new().set_dimmed(true))?; writeln!(&mut stdout, "{}", pv.indexedAt)?; stdout.reset()?; - write!(&mut stdout, " ")?; if let Some(entities) = &pv.record.entities { let mut cur: usize = 0; for ent in entities { @@ -92,7 +144,9 @@ pub fn pp_post_view(pv: &PostView) -> Result<()> { } } - writeln!(&mut stdout, "\n")?; + stdout.set_color(ColorSpec::new().set_dimmed(true))?; + writeln!(&mut stdout, "{}\n", pv.uri)?; + stdout.reset()?; Ok(()) } diff --git a/adenosine/src/app_bsky/mod.rs b/adenosine/src/app_bsky/mod.rs index d828bcb..76352f5 100644 --- a/adenosine/src/app_bsky/mod.rs +++ b/adenosine/src/app_bsky/mod.rs @@ -108,7 +108,6 @@ pub struct PostView { pub uri: String, pub cid: String, pub author: UserView, - pub repostedBy: Option, pub record: Post, pub embed: Option, pub replyCount: u64, @@ -122,9 +121,13 @@ pub struct PostView { #[allow(non_snake_case)] #[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)] pub struct ThreadPostView { - pub post: PostView, - // TODO: 'parent' and 'replies' should allow "NotFoundPost" for references that point to an - // unknown URI + // TODO: doing this as the intersetion of #threadViewPost and #notFoundPost. actually it is + // supposed to be a union type + // #notFoundPost fields (uri and notFound actually required) + pub uri: Option, + pub notFound: Option, + // #threadViewPost fields (post actually required) + pub post: Option, pub parent: Option>, pub replies: Option>, } @@ -134,7 +137,15 @@ pub struct ThreadPostView { pub struct FeedPostView { pub post: PostView, pub reply: Option, - pub reason: Option, + // TODO: this could extend to other "reasons" in the future + pub reason: Option, +} + +#[allow(non_snake_case)] +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)] +pub struct RepostReason { + pub by: UserView, + pub indexedAt: String, } #[allow(non_snake_case)] -- cgit v1.2.3