use clap::Subcommand;
use tail_fin_common::TailFinError;
use crate::session::{print_json, require_browser_session, Ctx};
#[derive(Subcommand)]
pub enum RedditAction {
Hot {
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Frontpage {
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Popular {
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Search {
query: String,
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Subreddit {
name: String,
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Read {
post_id: String,
#[arg(long, default_value_t = 5)]
depth: u32,
},
User { username: String },
UserPosts {
username: String,
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
UserComments {
username: String,
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Saved {
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Upvoted {
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
after: Option<String>,
},
Upvote { post_id: String },
Save { post_id: String },
Comment { post_id: String, text: String },
Subscribe {
subreddit: String,
},
}
pub async fn run(action: RedditAction, ctx: &Ctx) -> Result<(), TailFinError> {
let session = require_browser_session(ctx, "reddit").await?;
let client = tail_fin_reddit::RedditClient::new(session);
match action {
RedditAction::Hot { limit, after } => {
let resp = client.hot(limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Frontpage { limit, after } => {
let resp = client.frontpage(limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Popular { limit, after } => {
let resp = client.popular(limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Search {
query,
limit,
after,
} => {
let resp = client.search(&query, limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Subreddit { name, limit, after } => {
let resp = client.subreddit(&name, limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Read { post_id, depth } => {
let thread = client.read(&post_id, depth).await?;
print_json(&thread)?;
}
RedditAction::User { username } => {
let user = client.user(&username).await?;
print_json(&user)?;
}
RedditAction::UserPosts {
username,
limit,
after,
} => {
let resp = client
.user_posts(&username, limit, after.as_deref())
.await?;
print_json(&resp)?;
}
RedditAction::UserComments {
username,
limit,
after,
} => {
let resp = client
.user_comments(&username, limit, after.as_deref())
.await?;
print_json(&resp)?;
}
RedditAction::Saved { limit, after } => {
let resp = client.saved(limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Upvoted { limit, after } => {
let resp = client.upvoted(limit, after.as_deref()).await?;
print_json(&resp)?;
}
RedditAction::Upvote { post_id } => {
let result = client.upvote(&post_id).await?;
print_json(&result)?;
}
RedditAction::Save { post_id } => {
let result = client.save_post(&post_id).await?;
print_json(&result)?;
}
RedditAction::Comment { post_id, text } => {
let result = client.comment(&post_id, &text).await?;
print_json(&result)?;
}
RedditAction::Subscribe { subreddit } => {
let result = client.subscribe(&subreddit).await?;
print_json(&result)?;
}
}
Ok(())
}
pub struct Adapter;
impl crate::adapter::CliAdapter for Adapter {
fn name(&self) -> &'static str {
"reddit"
}
fn about(&self) -> &'static str {
"Reddit operations"
}
fn command(&self) -> clap::Command {
<RedditAction as clap::Subcommand>::augment_subcommands(
clap::Command::new("reddit").about("Reddit operations"),
)
}
fn dispatch<'a>(
&'a self,
matches: &'a clap::ArgMatches,
ctx: &'a crate::session::Ctx,
) -> std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<(), tail_fin_common::TailFinError>> + Send + 'a,
>,
> {
Box::pin(async move {
let action = <RedditAction as clap::FromArgMatches>::from_arg_matches(matches)
.map_err(|e| tail_fin_common::TailFinError::Api(e.to_string()))?;
run(action, ctx).await
})
}
}