summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbryan newbold <bnewbold@robocracy.org>2023-03-04 19:03:17 -0800
committerbryan newbold <bnewbold@robocracy.org>2023-03-04 19:03:17 -0800
commit97f030b15321bb22274fa2807da445aa5dfc5512 (patch)
treefebdb322f5f9f5b7a11764a1d50b83c596d6a911
parent33548eb9169c048456795e2cc999ada22465df4a (diff)
downloadadenosine-97f030b15321bb22274fa2807da445aa5dfc5512.tar.gz
adenosine-97f030b15321bb22274fa2807da445aa5dfc5512.zip
cli: improve 'pretty' output styling
-rw-r--r--adenosine-cli/src/pretty.rs62
-rw-r--r--adenosine/src/app_bsky/mod.rs21
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<UserView>,
pub record: Post,
pub embed: Option<PostEmbedView>,
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<String>,
+ pub notFound: Option<bool>,
+ // #threadViewPost fields (post actually required)
+ pub post: Option<PostView>,
pub parent: Option<Box<ThreadPostView>>,
pub replies: Option<Vec<ThreadPostView>>,
}
@@ -134,7 +137,15 @@ pub struct ThreadPostView {
pub struct FeedPostView {
pub post: PostView,
pub reply: Option<PostReply>,
- pub reason: Option<Value>,
+ // TODO: this could extend to other "reasons" in the future
+ pub reason: Option<RepostReason>,
+}
+
+#[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)]