summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCyborus <cyborus@cyborus.xyz>2024-06-18 05:38:58 +0200
committerCyborus <cyborus@cyborus.xyz>2024-07-08 20:54:57 +0200
commit3a008966742a780a4fff60d75d9165ff16b6dbca (patch)
treec06f83dccce93667a08605813d16e8e65bfd8234 /src
parentchore: `user.rs` file (diff)
downloadforgejo-cli-3a008966742a780a4fff60d75d9165ff16b6dbca.tar.xz
forgejo-cli-3a008966742a780a4fff60d75d9165ff16b6dbca.zip
feat(user): `user view` and `user browse`
Diffstat (limited to 'src')
-rw-r--r--src/main.rs6
-rw-r--r--src/user.rs107
2 files changed, 107 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs
index 48c2b03..e330f53 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -241,7 +241,7 @@ struct SpecialRender {
// blue: &'static str,
bright_blue: &'static str,
// cyan: &'static str,
- // bright_cyan: &'static str,
+ bright_cyan: &'static str,
yellow: &'static str,
// bright_yellow: &'static str,
// magenta: &'static str,
@@ -292,7 +292,7 @@ impl SpecialRender {
// blue: "\x1b[34m",
bright_blue: "\x1b[94m",
// cyan: "\x1b[36m",
- // bright_cyan: "\x1b[96m",
+ bright_cyan: "\x1b[96m",
yellow: "\x1b[33m",
// bright_yellow: "\x1b[93m",
// magenta: "\x1b[35m",
@@ -334,7 +334,7 @@ impl SpecialRender {
// blue: "",
bright_blue: "",
// cyan: "",
- // bright_cyan: "",
+ bright_cyan: "",
yellow: "",
// bright_yellow: "",
// magenta: "",
diff --git a/src/user.rs b/src/user.rs
index 0adceff..0b7b0ef 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -1,6 +1,8 @@
use clap::{Args, Subcommand};
+use eyre::OptionExt;
+use forgejo_api::Forgejo;
-use crate::repo::RepoInfo;
+use crate::{repo::RepoInfo, SpecialRender};
#[derive(Args, Clone, Debug)]
pub struct UserCommand {
@@ -11,13 +13,112 @@ pub struct UserCommand {
}
#[derive(Subcommand, Clone, Debug)]
-pub enum UserSubcommand {}
+pub enum UserSubcommand {
+ View {
+ /// The name of the user to view
+ user: Option<String>,
+ },
+ Browse {
+ /// The name of the user to open in your browser
+ user: Option<String>,
+ },
+}
impl UserCommand {
pub async fn run(self, keys: &mut crate::KeyInfo, host_name: Option<&str>) -> eyre::Result<()> {
let repo = RepoInfo::get_current(host_name, None, self.remote.as_deref())?;
let api = keys.get_api(repo.host_url()).await?;
- match self.command {}
+ match self.command {
+ UserSubcommand::View { user } => view_user(&api, user.as_deref()).await?,
+ UserSubcommand::Browse { user } => {
+ browse_user(&api, repo.host_url(), user.as_deref()).await?
+ }
+ }
Ok(())
}
}
+
+async fn view_user(api: &Forgejo, user: Option<&str>) -> eyre::Result<()> {
+ let SpecialRender {
+ bold,
+ dash,
+ bright_cyan,
+ light_grey,
+ reset,
+ ..
+ } = *crate::special_render();
+
+ let user_data = match user {
+ Some(user) => api.user_get(user).await?,
+ None => api.user_get_current().await?,
+ };
+ let username = user_data
+ .login
+ .as_deref()
+ .ok_or_eyre("user has no username")?;
+ print!("{bright_cyan}{bold}{username}{reset}");
+ if let Some(pronouns) = user_data.pronouns.as_deref() {
+ if !pronouns.is_empty() {
+ print!("{light_grey} {dash} {bold}{pronouns}{reset}");
+ }
+ }
+ println!();
+ let followers = user_data.followers_count.unwrap_or_default();
+ let following = user_data.following_count.unwrap_or_default();
+ println!("{bold}{followers}{reset} followers {dash} {bold}{following}{reset} following");
+ let mut first = true;
+ if let Some(website) = user_data.website.as_deref() {
+ if !website.is_empty() {
+ print!("{bold}{website}{reset}");
+ first = false;
+ }
+ }
+ if let Some(email) = user_data.email.as_deref() {
+ if !email.is_empty() && !email.contains("noreply") {
+ if !first {
+ print!(" {dash} ");
+ }
+ print!("{bold}{email}{reset}");
+ }
+ }
+ if !first {
+ println!();
+ }
+
+ if let Some(desc) = user_data.description.as_deref() {
+ if !desc.is_empty() {
+ println!();
+ println!("{}", crate::markdown(desc));
+ println!();
+ }
+ }
+
+ let joined = user_data
+ .created
+ .ok_or_eyre("user does not have join date")?;
+ let date_format = time::macros::format_description!("[month repr:short] [day], [year]");
+ println!("Joined on {bold}{}{reset}", joined.format(&date_format)?);
+
+ Ok(())
+}
+
+async fn browse_user(api: &Forgejo, host_url: &url::Url, user: Option<&str>) -> eyre::Result<()> {
+ let username = match user {
+ Some(user) => user.to_owned(),
+ None => {
+ let myself = api.user_get_current().await?;
+ myself
+ .login
+ .ok_or_eyre("authenticated user does not have login")?
+ }
+ };
+ // `User` doesn't have an `html_url` field, so we gotta construct the user
+ // page url ourselves
+ let mut url = host_url.clone();
+ url.path_segments_mut()
+ .map_err(|_| eyre::eyre!("invalid host url"))?
+ .push(&username);
+ open::that(url.as_str())?;
+
+ Ok(())
+}